| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use crate::{ |
| app::{InternalSender, MessageInternal}, |
| drawing::DisplayRotation, |
| geometry::{IntPoint, IntRect, IntSize, LimitToBounds, Size}, |
| view::ViewKey, |
| }; |
| use anyhow::{format_err, Error}; |
| use euclid::{default::Transform2D, point2, size2, vec2}; |
| use fidl::endpoints::create_proxy; |
| use fidl_fuchsia_input_report as hid_input_report; |
| use fuchsia_async::{self as fasync, Time, TimeoutExt}; |
| use fuchsia_zircon::{self as zx, Duration}; |
| use futures::TryFutureExt; |
| use input_synthesis::{ |
| keymaps::QWERTY_MAP, |
| usages::{input3_key_to_hid_usage, key_to_hid_usage}, |
| }; |
| use std::{ |
| collections::{HashMap, HashSet}, |
| fs::{self, DirEntry}, |
| hash::{Hash, Hasher}, |
| iter::FromIterator, |
| }; |
| |
| #[derive(Clone, Debug, Default, Eq, PartialEq, Hash)] |
| pub struct Button(pub u8); |
| |
| const PRIMARY_BUTTON: u8 = 1; |
| |
| impl Button { |
| pub fn is_primary(&self) -> bool { |
| self.0 == PRIMARY_BUTTON |
| } |
| } |
| |
| #[derive(Clone, Debug, Default, PartialEq)] |
| pub struct ButtonSet { |
| buttons: HashSet<Button>, |
| } |
| |
| impl ButtonSet { |
| pub fn new(buttons: &HashSet<u8>) -> ButtonSet { |
| ButtonSet { buttons: buttons.iter().map(|button| Button(*button)).collect() } |
| } |
| |
| pub fn new_from_flags(flags: u32) -> ButtonSet { |
| let buttons: HashSet<u8> = (0..2) |
| .filter_map(|index| { |
| let mask = 1 << index; |
| if flags & mask != 0 { |
| Some(index + 1) |
| } else { |
| None |
| } |
| }) |
| .collect(); |
| ButtonSet::new(&buttons) |
| } |
| |
| pub fn primary_button_is_down(&self) -> bool { |
| self.buttons.contains(&Button(PRIMARY_BUTTON)) |
| } |
| } |
| |
| #[derive(Debug, Default, PartialEq, Clone, Copy)] |
| pub struct Modifiers { |
| pub shift: bool, |
| pub alt: bool, |
| pub control: bool, |
| pub caps_lock: bool, |
| } |
| |
| impl Modifiers { |
| pub(crate) fn from_pressed_keys(pressed_keys: &HashSet<fidl_fuchsia_ui_input2::Key>) -> Self { |
| Self { |
| shift: pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::LeftShift) |
| || pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::RightShift), |
| alt: pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::LeftAlt) |
| || pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::RightAlt), |
| control: pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::LeftCtrl) |
| || pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::RightCtrl), |
| caps_lock: pressed_keys.contains(&fidl_fuchsia_ui_input2::Key::CapsLock), |
| } |
| } |
| |
| pub(crate) fn from_pressed_keys_3(pressed_keys: &HashSet<fidl_fuchsia_input::Key>) -> Self { |
| Self { |
| shift: pressed_keys.contains(&fidl_fuchsia_input::Key::LeftShift) |
| || pressed_keys.contains(&fidl_fuchsia_input::Key::RightShift), |
| alt: pressed_keys.contains(&fidl_fuchsia_input::Key::LeftAlt) |
| || pressed_keys.contains(&fidl_fuchsia_input::Key::RightAlt), |
| control: pressed_keys.contains(&fidl_fuchsia_input::Key::LeftCtrl) |
| || pressed_keys.contains(&fidl_fuchsia_input::Key::RightCtrl), |
| caps_lock: pressed_keys.contains(&fidl_fuchsia_input::Key::CapsLock), |
| } |
| } |
| } |
| |
| pub mod mouse { |
| use super::*; |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub enum Phase { |
| Down(Button), |
| Up(Button), |
| Moved, |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub buttons: ButtonSet, |
| pub phase: Phase, |
| pub location: IntPoint, |
| } |
| } |
| |
| #[cfg(test)] |
| mod mouse_tests { |
| use super::*; |
| |
| pub fn create_test_mouse_event(button: u8) -> Event { |
| let mouse_event = mouse::Event { |
| buttons: ButtonSet::default(), |
| phase: mouse::Phase::Down(Button(button)), |
| location: IntPoint::zero(), |
| }; |
| Event { |
| event_time: 0, |
| device_id: device_id_tests::create_test_device_id(), |
| event_type: EventType::Mouse(mouse_event), |
| } |
| } |
| } |
| |
| fn code_point_from_usage(hid_usage: usize, shift: bool) -> Option<u32> { |
| if hid_usage < QWERTY_MAP.len() { |
| if let Some(map_entry) = QWERTY_MAP[hid_usage] { |
| if shift { |
| map_entry.1.and_then(|shifted_char| Some(shifted_char as u32)) |
| } else { |
| Some(map_entry.0 as u32) |
| } |
| } else { |
| None |
| } |
| } else { |
| None |
| } |
| } |
| |
| pub mod keyboard { |
| use super::*; |
| |
| #[derive(Clone, Copy, Debug, PartialEq)] |
| pub enum Phase { |
| Pressed, |
| Released, |
| Cancelled, |
| Repeat, |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub phase: Phase, |
| pub code_point: Option<u32>, |
| pub hid_usage: u32, |
| pub modifiers: Modifiers, |
| } |
| } |
| |
| pub mod touch { |
| use super::*; |
| |
| #[derive(Debug, Eq)] |
| pub(crate) struct RawContact { |
| pub contact_id: u32, |
| pub position: IntPoint, |
| pub pressure: Option<i64>, |
| pub contact_size: Option<IntSize>, |
| } |
| |
| impl PartialEq for RawContact { |
| fn eq(&self, rhs: &Self) -> bool { |
| self.contact_id == rhs.contact_id |
| } |
| } |
| |
| impl Hash for RawContact { |
| fn hash<H: Hasher>(&self, state: &mut H) { |
| self.contact_id.hash(state); |
| } |
| } |
| |
| #[derive(Clone, Copy, Debug, Eq, Ord, PartialOrd, PartialEq, Hash)] |
| pub struct ContactId(pub u32); |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub enum Phase { |
| Down(IntPoint, IntSize), |
| Moved(IntPoint, IntSize), |
| Up, |
| Remove, |
| Cancel, |
| } |
| |
| #[derive(Debug, Clone, PartialEq)] |
| pub struct Contact { |
| pub contact_id: ContactId, |
| pub phase: Phase, |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub contacts: Vec<Contact>, |
| pub buttons: ButtonSet, |
| } |
| } |
| |
| #[cfg(test)] |
| mod touch_tests { |
| use super::*; |
| |
| pub fn create_test_contact() -> touch::Contact { |
| touch::Contact { |
| contact_id: touch::ContactId(100), |
| phase: touch::Phase::Down(IntPoint::zero(), IntSize::zero()), |
| } |
| } |
| } |
| |
| pub mod pointer { |
| use super::*; |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub enum Phase { |
| Down(IntPoint), |
| Moved(IntPoint), |
| Up, |
| Remove, |
| Cancel, |
| } |
| |
| #[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, Hash)] |
| pub enum PointerId { |
| Mouse(DeviceId), |
| Contact(touch::ContactId), |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub phase: Phase, |
| pub pointer_id: PointerId, |
| } |
| |
| impl Event { |
| pub fn new_from_mouse_event( |
| device_id: &DeviceId, |
| mouse_event: &mouse::Event, |
| ) -> Option<Self> { |
| match &mouse_event.phase { |
| mouse::Phase::Down(button) => { |
| if button.is_primary() { |
| Some(pointer::Phase::Down(mouse_event.location)) |
| } else { |
| None |
| } |
| } |
| mouse::Phase::Moved => { |
| if mouse_event.buttons.primary_button_is_down() { |
| Some(pointer::Phase::Moved(mouse_event.location)) |
| } else { |
| None |
| } |
| } |
| mouse::Phase::Up(button) => { |
| if button.is_primary() { |
| Some(pointer::Phase::Up) |
| } else { |
| None |
| } |
| } |
| } |
| .and_then(|phase| Some(Self { phase, pointer_id: PointerId::Mouse(device_id.clone()) })) |
| } |
| |
| pub fn new_from_contact(contact: &touch::Contact) -> Self { |
| let phase = match contact.phase { |
| touch::Phase::Down(location, ..) => pointer::Phase::Down(location), |
| touch::Phase::Moved(location, ..) => pointer::Phase::Moved(location), |
| touch::Phase::Up => pointer::Phase::Up, |
| touch::Phase::Remove => pointer::Phase::Remove, |
| touch::Phase::Cancel => pointer::Phase::Cancel, |
| }; |
| Self { phase, pointer_id: PointerId::Contact(contact.contact_id) } |
| } |
| } |
| } |
| |
| #[cfg(test)] |
| mod pointer_tests { |
| use super::*; |
| |
| #[test] |
| fn test_pointer_from_mouse() { |
| for button in 1..3 { |
| let event = mouse_tests::create_test_mouse_event(button); |
| match event.event_type { |
| EventType::Mouse(mouse_event) => { |
| let pointer_event = |
| pointer::Event::new_from_mouse_event(&event.device_id, &mouse_event); |
| assert_eq!(pointer_event.is_some(), button == 1); |
| } |
| _ => panic!("I asked for a mouse event"), |
| } |
| } |
| } |
| |
| #[test] |
| fn test_pointer_from_contact() { |
| let contact = touch_tests::create_test_contact(); |
| let pointer_event = pointer::Event::new_from_contact(&contact); |
| match pointer_event.phase { |
| pointer::Phase::Down(location) => { |
| assert_eq!(location, IntPoint::zero()); |
| } |
| _ => panic!("This should have been a down pointer event"), |
| } |
| } |
| } |
| |
| pub mod consumer_control { |
| use super::*; |
| |
| #[derive(Debug, PartialEq, Clone, Copy)] |
| pub enum Phase { |
| Down, |
| Up, |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub phase: Phase, |
| pub button: hid_input_report::ConsumerControlButton, |
| } |
| } |
| |
| #[derive(Clone, Debug, Default, Eq, PartialEq, Hash, PartialOrd, Ord)] |
| pub struct DeviceId(pub String); |
| |
| #[cfg(test)] |
| mod device_id_tests { |
| use super::*; |
| |
| pub fn create_test_device_id() -> DeviceId { |
| DeviceId("test-device-id-1".to_string()) |
| } |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub enum EventType { |
| Mouse(mouse::Event), |
| Keyboard(keyboard::Event), |
| Touch(touch::Event), |
| ConsumerControl(consumer_control::Event), |
| } |
| |
| #[derive(Debug, PartialEq, Clone)] |
| pub struct Event { |
| pub event_time: u64, |
| pub device_id: DeviceId, |
| pub event_type: EventType, |
| } |
| |
| fn device_id_for_event(event: &fidl_fuchsia_ui_input::PointerEvent) -> DeviceId { |
| let id_string = match event.type_ { |
| fidl_fuchsia_ui_input::PointerEventType::Touch => "touch", |
| fidl_fuchsia_ui_input::PointerEventType::Mouse => "mouse", |
| fidl_fuchsia_ui_input::PointerEventType::Stylus => "stylus", |
| fidl_fuchsia_ui_input::PointerEventType::InvertedStylus => "inverted-stylus", |
| }; |
| DeviceId(format!("{}-{}", id_string, event.device_id)) |
| } |
| |
| async fn listen_to_entry( |
| entry: &DirEntry, |
| view_key: ViewKey, |
| internal_sender: &InternalSender, |
| ) -> Result<(), Error> { |
| let (client, server) = zx::Channel::create()?; |
| fdio::service_connect(entry.path().to_str().expect("bad path"), server)?; |
| let client = fasync::Channel::from_channel(client)?; |
| let device = hid_input_report::InputDeviceProxy::new(client); |
| let descriptor = device |
| .get_descriptor() |
| .map_err(|err| format_err!("FIDL error on get_descriptor: {:?}", err)) |
| .on_timeout(Time::after(Duration::from_millis(200)), || { |
| Err(format_err!("FIDL timeout on get_descriptor")) |
| }) |
| .await?; |
| let device_id = entry.file_name().to_string_lossy().to_string(); |
| internal_sender |
| .unbounded_send(MessageInternal::RegisterDevice(DeviceId(device_id.clone()), descriptor)) |
| .expect("unbounded_send"); |
| let input_report_sender = internal_sender.clone(); |
| let (input_reports_reader_proxy, input_reports_reader_request) = create_proxy()?; |
| device.get_input_reports_reader(input_reports_reader_request)?; |
| fasync::Task::local(async move { |
| let _device = device; |
| loop { |
| let reports_res = input_reports_reader_proxy.read_input_reports().await; |
| match reports_res { |
| Ok(r) => match r { |
| Ok(reports) => { |
| for report in reports { |
| input_report_sender |
| .unbounded_send(MessageInternal::InputReport( |
| DeviceId(device_id.clone()), |
| view_key, |
| report, |
| )) |
| .expect("unbounded_send"); |
| } |
| } |
| Err(err) => { |
| eprintln!("Error report from read_input_reports: {}: {}", device_id, err); |
| } |
| }, |
| Err(err) => { |
| eprintln!("Error report from read_input_reports: {}: {}", device_id, err); |
| } |
| } |
| } |
| }) |
| .detach(); |
| Ok(()) |
| } |
| |
| pub(crate) async fn listen_for_user_input( |
| view_key: ViewKey, |
| internal_sender: InternalSender, |
| ) -> Result<(), Error> { |
| let input_devices_directory = "/dev/class/input-report"; |
| let path = std::path::Path::new(input_devices_directory); |
| let entries = fs::read_dir(path)?; |
| for entry in entries { |
| let entry = entry?; |
| match listen_to_entry(&entry, view_key, &internal_sender).await { |
| Err(err) => { |
| eprintln!("Error: {}: {}", entry.file_name().to_string_lossy().to_string(), err) |
| } |
| _ => (), |
| } |
| } |
| Ok(()) |
| } |
| |
| #[derive(Debug)] |
| struct TouchScale { |
| target_size: IntSize, |
| x: hid_input_report::Range, |
| x_span: f32, |
| y: hid_input_report::Range, |
| y_span: f32, |
| } |
| |
| fn restrict_to_range(value: i64, range: &hid_input_report::Range) -> i64 { |
| if value < range.min { |
| range.min |
| } else if value > range.max { |
| range.max |
| } else { |
| value |
| } |
| } |
| |
| fn scale_value(value: i64, span: f32, range: &hid_input_report::Range, value_max: i32) -> i32 { |
| let value = restrict_to_range(value, range) - range.min; |
| let value_fraction = value as f32 / span; |
| (value_fraction * value_max as f32) as i32 |
| } |
| |
| impl TouchScale { |
| fn calculate_span(range: &hid_input_report::Range) -> f32 { |
| if range.max <= range.min { |
| 1.0 |
| } else { |
| (range.max - range.min) as f32 |
| } |
| } |
| |
| pub fn new( |
| target_size: &IntSize, |
| x: &hid_input_report::Range, |
| y: &hid_input_report::Range, |
| ) -> Self { |
| Self { |
| target_size: *target_size, |
| x: *x, |
| x_span: Self::calculate_span(x), |
| y: *y, |
| y_span: Self::calculate_span(y), |
| } |
| } |
| |
| pub fn scale(&self, pt: &IntPoint) -> IntPoint { |
| let x = scale_value(pt.x as i64, self.x_span, &self.x, self.target_size.width); |
| let y = scale_value(pt.y as i64, self.y_span, &self.y, self.target_size.height); |
| point2(x, y) |
| } |
| } |
| |
| #[derive(Default)] |
| pub(crate) struct InputReportHandler { |
| view_size: IntSize, |
| display_rotation: DisplayRotation, |
| touch_scale: Option<TouchScale>, |
| cursor_position: IntPoint, |
| pressed_mouse_buttons: HashSet<u8>, |
| pressed_keys: HashSet<fidl_fuchsia_ui_input2::Key>, |
| raw_contacts: HashSet<touch::RawContact>, |
| pressed_consumer_control_buttons: HashSet<hid_input_report::ConsumerControlButton>, |
| } |
| |
| impl InputReportHandler { |
| pub fn new( |
| size: IntSize, |
| display_rotation: DisplayRotation, |
| device_descriptor: &hid_input_report::DeviceDescriptor, |
| ) -> InputReportHandler { |
| let touch_scale = device_descriptor |
| .touch |
| .as_ref() |
| .and_then(|touch| touch.input.as_ref()) |
| .and_then(|input_descriptor| input_descriptor.contacts.as_ref()) |
| .and_then(|contacts| contacts.first()) |
| .and_then(|contact_input_descriptor| { |
| if contact_input_descriptor.position_x.is_some() |
| && contact_input_descriptor.position_y.is_some() |
| { |
| Some(TouchScale::new( |
| &size, |
| &contact_input_descriptor.position_x.as_ref().expect("position_x").range, |
| &contact_input_descriptor.position_y.as_ref().expect("position_x").range, |
| )) |
| } else { |
| None |
| } |
| }); |
| Self::new_with_scale(size, display_rotation, touch_scale) |
| } |
| |
| fn new_with_scale( |
| size: IntSize, |
| display_rotation: DisplayRotation, |
| touch_scale: Option<TouchScale>, |
| ) -> Self { |
| Self { view_size: size, display_rotation, touch_scale, ..InputReportHandler::default() } |
| } |
| |
| fn handle_mouse_input_report( |
| &mut self, |
| event_time: u64, |
| device_id: &DeviceId, |
| mouse: &hid_input_report::MouseInputReport, |
| ) -> Vec<Event> { |
| fn create_mouse_event( |
| event_time: u64, |
| device_id: &DeviceId, |
| button_set: &ButtonSet, |
| cursor_position: IntPoint, |
| transform: &Transform2D<f32>, |
| phase: mouse::Phase, |
| ) -> Event { |
| let cursor_position = transform.transform_point(cursor_position.to_f32()).to_i32(); |
| let mouse_event = |
| mouse::Event { buttons: button_set.clone(), phase, location: cursor_position }; |
| Event { |
| event_time, |
| device_id: device_id.clone(), |
| event_type: EventType::Mouse(mouse_event), |
| } |
| } |
| |
| let transform = self.display_rotation.inv_transform(&self.view_size.to_f32()); |
| let new_cursor_position = self.cursor_position |
| + vec2(mouse.movement_x.unwrap_or(0) as i32, mouse.movement_y.unwrap_or(0) as i32); |
| let m = self.view_size; |
| let bounds = IntRect::new(IntPoint::zero(), m); |
| let new_cursor_position = bounds.limit_to_bounds(new_cursor_position); |
| let pressed_buttons: HashSet<u8> = if let Some(ref pressed_buttons) = mouse.pressed_buttons |
| { |
| let pressed_buttons_set = pressed_buttons.iter().cloned().collect(); |
| pressed_buttons_set |
| } else { |
| HashSet::new() |
| }; |
| |
| let button_set = ButtonSet::new(&pressed_buttons); |
| |
| let move_event = if new_cursor_position != self.cursor_position { |
| let event = create_mouse_event( |
| event_time, |
| device_id, |
| &button_set, |
| new_cursor_position, |
| &transform, |
| mouse::Phase::Moved, |
| ); |
| Some(event) |
| } else { |
| None |
| }; |
| |
| self.cursor_position = new_cursor_position; |
| |
| let newly_pressed = pressed_buttons.difference(&self.pressed_mouse_buttons).map(|button| { |
| create_mouse_event( |
| event_time, |
| device_id, |
| &button_set, |
| new_cursor_position, |
| &transform, |
| mouse::Phase::Down(Button(*button)), |
| ) |
| }); |
| |
| let released = self.pressed_mouse_buttons.difference(&pressed_buttons).map(|button| { |
| create_mouse_event( |
| event_time, |
| device_id, |
| &button_set, |
| new_cursor_position, |
| &transform, |
| mouse::Phase::Up(Button(*button)), |
| ) |
| }); |
| let events = newly_pressed.chain(move_event).chain(released).collect(); |
| self.pressed_mouse_buttons = pressed_buttons; |
| events |
| } |
| |
| fn handle_keyboard_input_report( |
| &mut self, |
| event_time: u64, |
| device_id: &DeviceId, |
| keyboard: &hid_input_report::KeyboardInputReport, |
| ) -> Vec<Event> { |
| fn create_keyboard_event( |
| event_time: u64, |
| device_id: &DeviceId, |
| phase: keyboard::Phase, |
| key: fidl_fuchsia_ui_input2::Key, |
| modifiers: &Modifiers, |
| ) -> Event { |
| let hid_usage = key_to_hid_usage(key); |
| let hid_usage_size = hid_usage as usize; |
| let code_point = code_point_from_usage(hid_usage_size, modifiers.shift); |
| let keyboard_event = |
| keyboard::Event { phase, code_point, hid_usage, modifiers: Modifiers::default() }; |
| Event { |
| event_time, |
| device_id: device_id.clone(), |
| event_type: EventType::Keyboard(keyboard_event), |
| } |
| } |
| |
| let pressed_keys: HashSet<fidl_fuchsia_ui_input2::Key> = |
| if let Some(ref pressed_keys) = keyboard.pressed_keys { |
| HashSet::from_iter(pressed_keys.iter().map(|key| *key)) |
| } else { |
| HashSet::new() |
| }; |
| |
| let modifiers = Modifiers::from_pressed_keys(&pressed_keys); |
| |
| let newly_pressed = pressed_keys.difference(&self.pressed_keys).map(|key| { |
| create_keyboard_event(event_time, device_id, keyboard::Phase::Pressed, *key, &modifiers) |
| }); |
| |
| let released = self.pressed_keys.difference(&pressed_keys).map(|key| { |
| create_keyboard_event( |
| event_time, |
| device_id, |
| keyboard::Phase::Released, |
| *key, |
| &modifiers, |
| ) |
| }); |
| |
| let events = newly_pressed.chain(released).collect(); |
| self.pressed_keys = pressed_keys; |
| events |
| } |
| |
| fn handle_touch_input_report( |
| &mut self, |
| event_time: u64, |
| device_id: &DeviceId, |
| touch: &hid_input_report::TouchInputReport, |
| ) -> Vec<Event> { |
| if self.touch_scale.is_none() { |
| return Vec::new(); |
| } |
| |
| let pressed_buttons: HashSet<u8> = if let Some(ref pressed_buttons) = touch.pressed_buttons |
| { |
| let pressed_buttons_set = pressed_buttons.iter().cloned().collect(); |
| pressed_buttons_set |
| } else { |
| HashSet::new() |
| }; |
| |
| let button_set = ButtonSet::new(&pressed_buttons); |
| |
| let raw_contacts: HashSet<touch::RawContact> = if let Some(ref contacts) = touch.contacts { |
| let id_iter = contacts.iter().filter_map(|contact| { |
| if contact.position_x.is_none() || contact.position_y.is_none() { |
| return None; |
| } |
| let contact_id = contact.contact_id.expect("contact_id"); |
| let contact_size = |
| if contact.contact_width.is_none() || contact.contact_height.is_none() { |
| None |
| } else { |
| Some(size2( |
| contact.contact_width.expect("contact_width") as i32, |
| contact.contact_height.expect("contact_height") as i32, |
| )) |
| }; |
| Some(touch::RawContact { |
| contact_id, |
| position: point2( |
| contact.position_x.expect("position_x") as i32, |
| contact.position_y.expect("position_y") as i32, |
| ), |
| contact_size, |
| pressure: contact.pressure, |
| }) |
| }); |
| HashSet::from_iter(id_iter) |
| } else { |
| HashSet::new() |
| }; |
| |
| let transform = self.display_rotation.inv_transform(&self.view_size.to_f32()); |
| let touch_scale = self.touch_scale.as_ref().expect("touch_scale"); |
| |
| let t = |point: IntPoint| transform.transform_point(point.to_f32()).to_i32(); |
| |
| let maintained_contacts = |
| self.raw_contacts.intersection(&raw_contacts).map(|raw_contact| touch::Contact { |
| contact_id: touch::ContactId(raw_contact.contact_id), |
| phase: touch::Phase::Moved( |
| t(touch_scale.scale(&raw_contact.position)), |
| raw_contact.contact_size.unwrap_or_else(|| IntSize::zero()), |
| ), |
| }); |
| |
| let new_contacts = |
| raw_contacts.difference(&self.raw_contacts).map(|raw_contact| touch::Contact { |
| contact_id: touch::ContactId(raw_contact.contact_id), |
| phase: touch::Phase::Down( |
| t(touch_scale.scale(&raw_contact.position)), |
| raw_contact.contact_size.unwrap_or_else(|| IntSize::zero()), |
| ), |
| }); |
| |
| let ended_contacts = |
| self.raw_contacts.difference(&raw_contacts).map(|raw_contact| touch::Contact { |
| contact_id: touch::ContactId(raw_contact.contact_id), |
| phase: touch::Phase::Up, |
| }); |
| |
| let contacts: Vec<touch::Contact> = |
| new_contacts.chain(maintained_contacts).chain(ended_contacts).collect(); |
| |
| self.raw_contacts = raw_contacts; |
| |
| let touch_event = touch::Event { contacts: contacts, buttons: button_set }; |
| let event = Event { |
| event_time, |
| device_id: device_id.clone(), |
| event_type: EventType::Touch(touch_event), |
| }; |
| vec![event] |
| } |
| |
| fn handle_consumer_control_report( |
| &mut self, |
| event_time: u64, |
| device_id: &DeviceId, |
| consumer_control: &hid_input_report::ConsumerControlInputReport, |
| ) -> Vec<Event> { |
| fn create_consumer_control_event( |
| event_time: u64, |
| device_id: &DeviceId, |
| phase: consumer_control::Phase, |
| button: hid_input_report::ConsumerControlButton, |
| ) -> Event { |
| let consumer_control_event = consumer_control::Event { phase, button }; |
| Event { |
| event_time, |
| device_id: device_id.clone(), |
| event_type: EventType::ConsumerControl(consumer_control_event), |
| } |
| } |
| |
| let pressed_consumer_control_buttons: HashSet<hid_input_report::ConsumerControlButton> = |
| if let Some(ref pressed_buttons) = consumer_control.pressed_buttons { |
| let pressed_buttons_set = pressed_buttons.iter().cloned().collect(); |
| pressed_buttons_set |
| } else { |
| HashSet::new() |
| }; |
| let newly_pressed = pressed_consumer_control_buttons |
| .difference(&self.pressed_consumer_control_buttons) |
| .map(|button| { |
| create_consumer_control_event( |
| event_time, |
| device_id, |
| consumer_control::Phase::Down, |
| *button, |
| ) |
| }); |
| |
| let released = self |
| .pressed_consumer_control_buttons |
| .difference(&pressed_consumer_control_buttons) |
| .map(|button| { |
| create_consumer_control_event( |
| event_time, |
| device_id, |
| consumer_control::Phase::Up, |
| *button, |
| ) |
| }); |
| let events = newly_pressed.chain(released).collect(); |
| self.pressed_consumer_control_buttons = pressed_consumer_control_buttons; |
| events |
| } |
| |
| pub fn handle_input_report( |
| &mut self, |
| device_id: &DeviceId, |
| input_report: &hid_input_report::InputReport, |
| ) -> Vec<Event> { |
| let mut events = Vec::new(); |
| let event_time = input_report.event_time.unwrap_or(0) as u64; |
| if let Some(mouse) = input_report.mouse.as_ref() { |
| events.extend(self.handle_mouse_input_report(event_time, device_id, mouse)); |
| } |
| if let Some(keyboard) = input_report.keyboard.as_ref() { |
| events.extend(self.handle_keyboard_input_report(event_time, &device_id, keyboard)); |
| } |
| if let Some(touch) = input_report.touch.as_ref() { |
| events.extend(self.handle_touch_input_report(event_time, &device_id, touch)); |
| } |
| if let Some(consumer_control) = input_report.consumer_control.as_ref() { |
| events.extend(self.handle_consumer_control_report( |
| event_time, |
| &device_id, |
| consumer_control, |
| )); |
| } |
| events |
| } |
| } |
| |
| #[cfg(test)] |
| mod input_report_tests { |
| use super::*; |
| use itertools::assert_equal; |
| |
| fn make_input_handler() -> InputReportHandler { |
| let test_size = size2(1024, 768); |
| let touch_scale = TouchScale { |
| target_size: test_size, |
| x: fidl_fuchsia_input_report::Range { min: 0, max: 4095 }, |
| x_span: 4095.0, |
| y: fidl_fuchsia_input_report::Range { min: 0, max: 4095 }, |
| y_span: 4095.0, |
| }; |
| InputReportHandler::new_with_scale(test_size, DisplayRotation::Deg0, Some(touch_scale)) |
| } |
| |
| #[test] |
| fn test_typed_string() { |
| let reports = test_data::hello_world_keyboard_reports(); |
| |
| let mut input_handler = make_input_handler(); |
| |
| let device_id = DeviceId("keyboard-1".to_string()); |
| let chars_from_events = reports |
| .iter() |
| .map(|input_report| input_handler.handle_input_report(&device_id, input_report)) |
| .flatten() |
| .filter_map(|event| match event.event_type { |
| EventType::Keyboard(keyboard_event) => match keyboard_event.phase { |
| keyboard::Phase::Pressed => keyboard_event |
| .code_point |
| .and_then(|code_point| Some(code_point as u8 as char)), |
| _ => None, |
| }, |
| _ => None, |
| }); |
| |
| assert_equal("Hello World".chars(), chars_from_events); |
| } |
| |
| #[test] |
| fn test_touch_drag() { |
| let reports = test_data::touch_drag_input_reports(); |
| |
| let device_id = DeviceId("touch-1".to_string()); |
| |
| let mut input_handler = make_input_handler(); |
| |
| let events = reports |
| .iter() |
| .map(|input_report| input_handler.handle_input_report(&device_id, input_report)) |
| .flatten(); |
| |
| let mut start_point = IntPoint::zero(); |
| let mut end_point = IntPoint::zero(); |
| let mut move_count = 0; |
| for event in events { |
| match event.event_type { |
| EventType::Touch(touch_event) => { |
| let contact = touch_event.contacts.iter().nth(0).expect("first contact"); |
| match contact.phase { |
| touch::Phase::Down(location, _) => { |
| start_point = location; |
| } |
| touch::Phase::Moved(location, _) => { |
| end_point = location; |
| move_count += 1; |
| } |
| _ => (), |
| } |
| } |
| _ => (), |
| } |
| } |
| |
| assert_eq!(start_point, point2(302, 491)); |
| assert_eq!(end_point, point2(637, 21)); |
| assert_eq!(move_count, 15); |
| } |
| |
| #[test] |
| fn test_mouse_drag() { |
| let reports = test_data::mouse_drag_input_reports(); |
| |
| let device_id = DeviceId("touch-1".to_string()); |
| |
| let mut input_handler = make_input_handler(); |
| let events = reports |
| .iter() |
| .map(|input_report| input_handler.handle_input_report(&device_id, input_report)) |
| .flatten(); |
| |
| let mut start_point = IntPoint::zero(); |
| let mut end_point = IntPoint::zero(); |
| let mut move_count = 0; |
| let mut down_button = None; |
| for event in events { |
| match event.event_type { |
| EventType::Mouse(mouse_event) => match mouse_event.phase { |
| mouse::Phase::Down(button) => { |
| assert!(down_button.is_none()); |
| assert!(button.is_primary()); |
| start_point = mouse_event.location; |
| down_button = Some(button); |
| } |
| mouse::Phase::Moved => { |
| end_point = mouse_event.location; |
| move_count += 1; |
| } |
| mouse::Phase::Up(button) => { |
| assert!(button.is_primary()); |
| } |
| }, |
| _ => (), |
| } |
| } |
| |
| assert!(down_button.expect("down_button").is_primary()); |
| assert_eq!(start_point, point2(129, 44)); |
| assert_eq!(end_point, point2(616, 213)); |
| assert_eq!(move_count, 181); |
| } |
| |
| #[test] |
| fn test_consumer_control() { |
| use hid_input_report::ConsumerControlButton::{VolumeDown, VolumeUp}; |
| let reports = test_data::consumer_control_input_reports(); |
| |
| let device_id = DeviceId("cc-1".to_string()); |
| |
| let mut input_handler = make_input_handler(); |
| let events: Vec<(consumer_control::Phase, hid_input_report::ConsumerControlButton)> = |
| reports |
| .iter() |
| .map(|input_report| input_handler.handle_input_report(&device_id, input_report)) |
| .flatten() |
| .filter_map(|event| match event.event_type { |
| EventType::ConsumerControl(consumer_control_event) => { |
| Some((consumer_control_event.phase, consumer_control_event.button)) |
| } |
| _ => None, |
| }) |
| .collect(); |
| |
| let expected = [ |
| (consumer_control::Phase::Down, VolumeUp), |
| (consumer_control::Phase::Up, VolumeUp), |
| (consumer_control::Phase::Down, VolumeDown), |
| (consumer_control::Phase::Up, VolumeDown), |
| ]; |
| assert_eq!(events, expected); |
| } |
| } |
| |
| // Scenic has a logical/physical coordinate system scheme that Carnelian does not currently |
| // want to expose. |
| fn to_physical_point(x: f32, y: f32, metrics: &Size) -> IntPoint { |
| let x = x * metrics.width; |
| let y = y * metrics.height; |
| point2(x as i32, y as i32) |
| } |
| |
| #[derive(Default)] |
| pub(crate) struct ScenicInputHandler { |
| contacts: HashMap<u32, touch::Contact>, |
| keyboard_device_id: DeviceId, |
| pressed_keys: HashSet<fidl_fuchsia_input::Key>, |
| } |
| |
| impl ScenicInputHandler { |
| pub fn new() -> Self { |
| Self { |
| keyboard_device_id: DeviceId("scenic-keyboard".to_string()), |
| contacts: HashMap::new(), |
| pressed_keys: HashSet::new(), |
| } |
| } |
| |
| fn convert_scenic_mouse_phase( |
| &self, |
| event: &fidl_fuchsia_ui_input::PointerEvent, |
| ) -> Option<mouse::Phase> { |
| let buttons = event.buttons; |
| let pressed_buttons: HashSet<u8> = (0..3) |
| .filter_map(|index| if buttons & 1 << index != 0 { Some(index + 1) } else { None }) |
| .collect(); |
| match event.phase { |
| fidl_fuchsia_ui_input::PointerEventPhase::Down => pressed_buttons |
| .iter() |
| .nth(0) |
| .and_then(|button| Some(mouse::Phase::Down(Button(*button)))), |
| fidl_fuchsia_ui_input::PointerEventPhase::Move => Some(mouse::Phase::Moved), |
| fidl_fuchsia_ui_input::PointerEventPhase::Up => pressed_buttons |
| .iter() |
| .nth(0) |
| .and_then(|button| Some(mouse::Phase::Up(Button(*button)))), |
| _ => None, |
| } |
| } |
| |
| fn handle_touch_event( |
| &mut self, |
| metrics: &Size, |
| event: &fidl_fuchsia_ui_input::PointerEvent, |
| ) -> Option<Event> { |
| let device_id = device_id_for_event(event); |
| let location = to_physical_point(event.x, event.y, metrics); |
| let phase = match event.phase { |
| fidl_fuchsia_ui_input::PointerEventPhase::Down => { |
| Some(touch::Phase::Down(location, IntSize::zero())) |
| } |
| fidl_fuchsia_ui_input::PointerEventPhase::Move => { |
| Some(touch::Phase::Moved(location, IntSize::zero())) |
| } |
| fidl_fuchsia_ui_input::PointerEventPhase::Up => Some(touch::Phase::Up), |
| fidl_fuchsia_ui_input::PointerEventPhase::Remove => Some(touch::Phase::Remove), |
| fidl_fuchsia_ui_input::PointerEventPhase::Cancel => Some(touch::Phase::Cancel), |
| _ => None, |
| }; |
| |
| if let Some(phase) = phase { |
| let contact = touch::Contact { contact_id: touch::ContactId(event.pointer_id), phase }; |
| self.contacts.insert(event.pointer_id, contact); |
| let contacts: Vec<touch::Contact> = self.contacts.values().map(|v| v.clone()).collect(); |
| self.contacts.retain(|_, contact| match contact.phase { |
| touch::Phase::Remove => false, |
| touch::Phase::Cancel => false, |
| _ => true, |
| }); |
| let buttons = ButtonSet::new_from_flags(event.buttons); |
| let touch_event = touch::Event { buttons, contacts }; |
| let new_event = Event { |
| event_type: EventType::Touch(touch_event), |
| device_id: device_id, |
| event_time: event.event_time, |
| }; |
| Some(new_event) |
| } else { |
| None |
| } |
| } |
| |
| fn handle_scenic_pointer_event( |
| &mut self, |
| metrics: &Size, |
| event: &fidl_fuchsia_ui_input::PointerEvent, |
| ) -> Vec<Event> { |
| let mut events = Vec::new(); |
| let location = to_physical_point(event.x, event.y, metrics); |
| match event.type_ { |
| fidl_fuchsia_ui_input::PointerEventType::Touch => { |
| let new_event = self.handle_touch_event(metrics, event); |
| events.extend(new_event); |
| } |
| fidl_fuchsia_ui_input::PointerEventType::Mouse => { |
| if let Some(phase) = self.convert_scenic_mouse_phase(&event) { |
| let device_id = device_id_for_event(event); |
| let mouse_input = mouse::Event { |
| location, |
| buttons: ButtonSet::new_from_flags(event.buttons), |
| phase: phase, |
| }; |
| let new_event = Event { |
| event_type: EventType::Mouse(mouse_input), |
| device_id: device_id, |
| event_time: event.event_time, |
| }; |
| events.push(new_event); |
| } |
| } |
| _ => (), |
| } |
| events |
| } |
| |
| pub fn handle_scenic_input_event( |
| &mut self, |
| metrics: &Size, |
| event: &fidl_fuchsia_ui_input::InputEvent, |
| ) -> Vec<Event> { |
| let mut events = Vec::new(); |
| match event { |
| fidl_fuchsia_ui_input::InputEvent::Pointer(pointer_event) => { |
| events.extend(self.handle_scenic_pointer_event(metrics, &pointer_event)); |
| } |
| _ => (), |
| } |
| events |
| } |
| |
| pub fn handle_scenic_key_event( |
| &mut self, |
| event: &fidl_fuchsia_ui_input3::KeyEvent, |
| ) -> Vec<Event> { |
| if event.type_.is_none() || event.timestamp.is_none() || event.key.is_none() { |
| println!("Malformed scenic key event {:?}", event); |
| return vec![]; |
| } |
| let event_type = event.type_.unwrap(); |
| let timestamp = event.timestamp.unwrap() as u64; |
| let key = event.key.unwrap(); |
| let phase: Option<keyboard::Phase> = match event_type { |
| fidl_fuchsia_ui_input3::KeyEventType::Pressed => Some(keyboard::Phase::Pressed), |
| fidl_fuchsia_ui_input3::KeyEventType::Released => Some(keyboard::Phase::Released), |
| fidl_fuchsia_ui_input3::KeyEventType::Cancel => Some(keyboard::Phase::Cancelled), |
| // The input3 sync feature is not supported |
| fidl_fuchsia_ui_input3::KeyEventType::Sync => None, |
| }; |
| if phase.is_none() { |
| return vec![]; |
| } |
| let phase = phase.unwrap(); |
| |
| match phase { |
| keyboard::Phase::Pressed => { |
| self.pressed_keys.insert(key); |
| } |
| keyboard::Phase::Released | keyboard::Phase::Cancelled => { |
| self.pressed_keys.remove(&key); |
| } |
| _ => (), |
| } |
| |
| let device_id = self.keyboard_device_id.clone(); |
| let hid_usage = input3_key_to_hid_usage(key); |
| let modifiers = Modifiers::from_pressed_keys_3(&self.pressed_keys); |
| let code_point = code_point_from_usage(hid_usage as usize, modifiers.shift); |
| let keyboard_event = keyboard::Event { code_point, hid_usage, modifiers, phase }; |
| |
| let event = Event { |
| event_time: timestamp, |
| event_type: EventType::Keyboard(keyboard_event), |
| device_id, |
| }; |
| |
| vec![event] |
| } |
| } |
| |
| #[cfg(test)] |
| mod scenic_input_tests { |
| use super::*; |
| use itertools::assert_equal; |
| |
| #[test] |
| fn test_typed_string() { |
| let scenic_events = test_data::hello_world_scenic_input_events(); |
| |
| let mut scenic_input_handler = ScenicInputHandler::new(); |
| let chars_from_events = scenic_events |
| .iter() |
| .map(|event| scenic_input_handler.handle_scenic_key_event(event)) |
| .flatten() |
| .filter_map(|event| match event.event_type { |
| EventType::Keyboard(keyboard_event) => match keyboard_event.phase { |
| keyboard::Phase::Pressed => keyboard_event |
| .code_point |
| .and_then(|code_point| Some(code_point as u8 as char)), |
| _ => None, |
| }, |
| _ => None, |
| }); |
| |
| assert_equal("Hello World".chars(), chars_from_events); |
| } |
| |
| #[test] |
| fn test_control_r() { |
| let scenic_events = test_data::control_r_scenic_events(); |
| |
| // make sure there's one and only one keydown even of the r |
| // key with the control modifier set. |
| let mut scenic_input_handler = ScenicInputHandler::new(); |
| let expected_event_count: usize = scenic_events |
| .iter() |
| .map(|event| scenic_input_handler.handle_scenic_key_event(event)) |
| .flatten() |
| .filter_map(|event| match event.event_type { |
| EventType::Keyboard(keyboard_event) => match keyboard_event.phase { |
| keyboard::Phase::Pressed => { |
| if keyboard_event.hid_usage |
| == input_synthesis::usages::Usages::HidUsageKeyR as u32 |
| && keyboard_event.modifiers.control |
| { |
| Some(()) |
| } else { |
| None |
| } |
| } |
| _ => None, |
| }, |
| _ => None, |
| }) |
| .count(); |
| |
| assert_eq!(expected_event_count, 1); |
| } |
| |
| #[test] |
| fn test_touch_drag() { |
| let scenic_events = test_data::touch_drag_scenic_events(); |
| let mut scenic_input_handler = ScenicInputHandler::new(); |
| let metrics = size2(1.0, 1.0); |
| let input_events = scenic_events |
| .iter() |
| .map(|event| scenic_input_handler.handle_scenic_input_event(&metrics, event)) |
| .flatten(); |
| |
| let mut start_point = IntPoint::zero(); |
| let mut end_point = IntPoint::zero(); |
| let mut move_count = 0; |
| for event in input_events { |
| match event.event_type { |
| EventType::Touch(touch_event) => { |
| let contact = touch_event.contacts.iter().nth(0).expect("first contact"); |
| match contact.phase { |
| touch::Phase::Down(location, _) => { |
| start_point = location; |
| } |
| touch::Phase::Moved(location, _) => { |
| end_point = location; |
| move_count += 1; |
| } |
| _ => (), |
| } |
| } |
| _ => (), |
| } |
| } |
| |
| assert_eq!(start_point, point2(193, 107)); |
| assert_eq!(end_point, point2(269, 157)); |
| assert_eq!(move_count, 8); |
| } |
| |
| #[test] |
| fn test_mouse_drag() { |
| let scenic_events = test_data::mouse_drag_scenic_events(); |
| let mut scenic_input_handler = ScenicInputHandler::new(); |
| let metrics = size2(1.0, 1.0); |
| let input_events = scenic_events |
| .iter() |
| .map(|event| scenic_input_handler.handle_scenic_input_event(&metrics, event)) |
| .flatten(); |
| |
| let mut start_point = IntPoint::zero(); |
| let mut end_point = IntPoint::zero(); |
| let mut move_count = 0; |
| let mut down_button = None; |
| for event in input_events { |
| match event.event_type { |
| EventType::Mouse(mouse_event) => match mouse_event.phase { |
| mouse::Phase::Down(button) => { |
| assert!(down_button.is_none()); |
| assert!(button.is_primary()); |
| start_point = mouse_event.location; |
| down_button = Some(button); |
| } |
| mouse::Phase::Moved => { |
| end_point = mouse_event.location; |
| move_count += 1; |
| } |
| mouse::Phase::Up(button) => { |
| assert!(button.is_primary()); |
| } |
| }, |
| _ => (), |
| } |
| } |
| |
| assert!(down_button.expect("down_button").is_primary()); |
| assert_eq!(start_point, point2(67, 62)); |
| assert_eq!(end_point, point2(128, 136)); |
| assert_eq!(move_count, 36); |
| } |
| } |
| |
| #[cfg(test)] |
| mod test_data { |
| pub fn consumer_control_input_reports() -> Vec<fidl_fuchsia_input_report::InputReport> { |
| use fidl_fuchsia_input_report::{ |
| ConsumerControlButton::{VolumeDown, VolumeUp}, |
| ConsumerControlInputReport, InputReport, |
| }; |
| vec![ |
| InputReport { |
| event_time: Some(66268999833), |
| mouse: None, |
| trace_id: Some(2), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: Some(ConsumerControlInputReport { |
| pressed_buttons: Some([VolumeUp].to_vec()), |
| ..ConsumerControlInputReport::EMPTY |
| }), |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(66434561666), |
| mouse: None, |
| trace_id: Some(3), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: Some(ConsumerControlInputReport { |
| pressed_buttons: Some([].to_vec()), |
| ..ConsumerControlInputReport::EMPTY |
| }), |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(358153537000), |
| mouse: None, |
| trace_id: Some(4), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: Some(ConsumerControlInputReport { |
| pressed_buttons: Some([VolumeDown].to_vec()), |
| ..ConsumerControlInputReport::EMPTY |
| }), |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(358376260958), |
| mouse: None, |
| trace_id: Some(5), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: Some(ConsumerControlInputReport { |
| pressed_buttons: Some([].to_vec()), |
| ..ConsumerControlInputReport::EMPTY |
| }), |
| ..InputReport::EMPTY |
| }, |
| ] |
| } |
| pub fn hello_world_keyboard_reports() -> Vec<fidl_fuchsia_input_report::InputReport> { |
| use { |
| fidl_fuchsia_input_report::{InputReport, KeyboardInputReport}, |
| fidl_fuchsia_ui_input2::Key::*, |
| }; |
| vec![ |
| InputReport { |
| event_time: Some(85446402710730), |
| mouse: None, |
| trace_id: Some(189), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![LeftShift]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85446650713601), |
| mouse: None, |
| trace_id: Some(191), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![LeftShift, H]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85446738712880), |
| mouse: None, |
| trace_id: Some(193), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![LeftShift]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85446794702907), |
| mouse: None, |
| trace_id: Some(195), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85446970709193), |
| mouse: None, |
| trace_id: Some(197), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![E]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447090710657), |
| mouse: None, |
| trace_id: Some(199), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447330708990), |
| mouse: None, |
| trace_id: Some(201), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![L]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447394712460), |
| mouse: None, |
| trace_id: Some(203), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447508813465), |
| mouse: None, |
| trace_id: Some(205), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![L]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447618712982), |
| mouse: None, |
| trace_id: Some(207), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447810705156), |
| mouse: None, |
| trace_id: Some(209), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![O]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85447898703263), |
| mouse: None, |
| trace_id: Some(211), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450082706011), |
| mouse: None, |
| trace_id: Some(213), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![Space]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450156060503), |
| mouse: None, |
| trace_id: Some(215), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450418710803), |
| mouse: None, |
| trace_id: Some(217), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![LeftShift]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450594712232), |
| mouse: None, |
| trace_id: Some(219), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![LeftShift, W]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450746707982), |
| mouse: None, |
| trace_id: Some(221), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![W]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450794706822), |
| mouse: None, |
| trace_id: Some(223), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85450962706591), |
| mouse: None, |
| trace_id: Some(225), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![O]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85451050703903), |
| mouse: None, |
| trace_id: Some(227), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85451282710803), |
| mouse: None, |
| trace_id: Some(229), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![R]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85451411293149), |
| mouse: None, |
| trace_id: Some(231), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85451842714565), |
| mouse: None, |
| trace_id: Some(233), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![L]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85451962704075), |
| mouse: None, |
| trace_id: Some(235), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85452906710709), |
| mouse: None, |
| trace_id: Some(237), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![D]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85453034711602), |
| mouse: None, |
| trace_id: Some(239), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85454778708461), |
| mouse: None, |
| trace_id: Some(241), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![Enter]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(85454858706151), |
| mouse: None, |
| trace_id: Some(243), |
| sensor: None, |
| touch: None, |
| keyboard: Some(KeyboardInputReport { |
| pressed_keys: Some(vec![]), |
| pressed_keys3: None, |
| ..KeyboardInputReport::EMPTY |
| }), |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| ] |
| } |
| |
| pub fn touch_drag_input_reports() -> Vec<fidl_fuchsia_input_report::InputReport> { |
| use fidl_fuchsia_input_report::{ContactInputReport, InputReport, TouchInputReport}; |
| |
| vec![ |
| InputReport { |
| event_time: Some(2129689875195), |
| mouse: None, |
| trace_id: Some(294), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1211), |
| position_y: Some(2621), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129715875833), |
| mouse: None, |
| trace_id: Some(295), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1211), |
| position_y: Some(2621), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129741874822), |
| mouse: None, |
| trace_id: Some(296), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1223), |
| position_y: Some(2607), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129767876545), |
| mouse: None, |
| trace_id: Some(297), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1267), |
| position_y: Some(2539), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129793872236), |
| mouse: None, |
| trace_id: Some(298), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1391), |
| position_y: Some(2300), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129818875839), |
| mouse: None, |
| trace_id: Some(299), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1523), |
| position_y: Some(2061), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129844873276), |
| mouse: None, |
| trace_id: Some(300), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1675), |
| position_y: Some(1781), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129870884557), |
| mouse: None, |
| trace_id: Some(301), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1743), |
| position_y: Some(1652), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129896870474), |
| mouse: None, |
| trace_id: Some(302), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(1875), |
| position_y: Some(1399), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129922876931), |
| mouse: None, |
| trace_id: Some(303), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2015), |
| position_y: Some(1174), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129948875990), |
| mouse: None, |
| trace_id: Some(304), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2143), |
| position_y: Some(935), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129973877732), |
| mouse: None, |
| trace_id: Some(305), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2275), |
| position_y: Some(682), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2129998870634), |
| mouse: None, |
| trace_id: Some(306), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2331), |
| position_y: Some(566), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2130023872212), |
| mouse: None, |
| trace_id: Some(307), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2439), |
| position_y: Some(314), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2130048871365), |
| mouse: None, |
| trace_id: Some(308), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2551), |
| position_y: Some(116), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2130071873308), |
| mouse: None, |
| trace_id: Some(309), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![ContactInputReport { |
| contact_id: Some(0), |
| position_x: Some(2643), |
| position_y: Some(54), |
| pressure: None, |
| contact_width: None, |
| contact_height: None, |
| ..ContactInputReport::EMPTY |
| }]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(2130110871653), |
| mouse: None, |
| trace_id: Some(310), |
| sensor: None, |
| touch: Some(TouchInputReport { |
| contacts: Some(vec![]), |
| pressed_buttons: Some(vec![]), |
| ..TouchInputReport::EMPTY |
| }), |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| ] |
| } |
| |
| pub fn mouse_drag_input_reports() -> Vec<fidl_fuchsia_input_report::InputReport> { |
| use fidl_fuchsia_input_report::{InputReport, MouseInputReport}; |
| vec![ |
| InputReport { |
| event_time: Some(101114216676), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(-1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(1), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101122479286), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(3), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101130223338), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(4), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101139198674), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(-1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(5), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101154621806), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(3), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(6), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101162221969), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(7), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101170222632), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(-1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(8), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101178218319), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(9), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101195538881), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(10), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101202218423), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(11), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101210236557), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(12), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101218244736), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(3), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(13), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101226633284), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(14), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101235789939), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(4), |
| movement_y: Some(3), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(15), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101242227234), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(16), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101250552651), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(6), |
| movement_y: Some(3), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(17), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101258523666), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(4), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(18), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101266879375), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(4), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(19), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101279470078), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(5), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(20), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101282237222), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(5), |
| movement_y: Some(3), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(21), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101290229686), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(5), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(22), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101298227434), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(5), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(23), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101306236833), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(3), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(24), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101314225440), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(4), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(25), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101322221224), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(4), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(26), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101330220567), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(27), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101338229995), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(3), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(28), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101346226157), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(29), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101354223947), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(30), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101362223006), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(31), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101370218719), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(2), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(32), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101378220583), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(2), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(33), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101386213038), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(1), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..MouseInputReport::EMPTY |
| }), |
| trace_id: Some(34), |
| sensor: None, |
| touch: None, |
| keyboard: None, |
| consumer_control: None, |
| ..InputReport::EMPTY |
| }, |
| InputReport { |
| event_time: Some(101394217453), |
| mouse: Some(MouseInputReport { |
| movement_x: Some(1), |
| movement_y: Some(0), |
| scroll_v: Some(0), |
| scroll_h: None, |
| pressed_buttons: Some(vec![]), |
| position_x: None, |
| position_y: None, |
| ..<
|