blob: 19777aa887067655b23bdc83254fbe4db7887e8e [file] [log] [blame]
// 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 {
anyhow::{Context, Error},
async_trait::async_trait,
fidl_fuchsia_ui_scenic::ScenicMarker,
fuchsia_async as fasync,
fuchsia_component::client::connect_to_service,
fuchsia_syslog as fsyslog,
input::{
input_device, input_handler::InputHandler, input_pipeline::InputPipeline, mouse, Position,
},
scene_management::{self, SceneManager, ScreenCoordinates},
};
/// A simple InputHandler that draws a cursor on screen.
struct SimpleCursor {
position: Position,
max_position: Position,
scene_manager: scene_management::FlatSceneManager,
}
#[async_trait]
impl InputHandler for SimpleCursor {
async fn handle_input_event(
&mut self,
input_event: input_device::InputEvent,
) -> Vec<input_device::InputEvent> {
match input_event {
input_device::InputEvent {
device_event: input_device::InputDeviceEvent::Mouse(mouse_event),
device_descriptor: input_device::InputDeviceDescriptor::Mouse(_mouse_descriptor),
event_time: _,
} => {
self.position = match mouse_event.location {
mouse::MouseLocation::Relative(offset) if offset != Position::zero() => {
self.position + offset
}
mouse::MouseLocation::Absolute(position) if position != self.position => {
position
}
_ => return vec![],
};
Position::clamp(&mut self.position, Position { x: 0.0, y: 0.0 }, self.max_position);
self.scene_manager.set_cursor_location(ScreenCoordinates::from_position(
&self.position,
self.scene_manager.display_metrics,
));
vec![]
}
_ => vec![input_event],
}
}
}
/// Connects to the `scenic` service and creates an instance of the `FlatSceneManager`. It then
/// sets the cursor position to the middle of the screen.
#[fasync::run_singlethreaded]
async fn main() -> Result<(), Error> {
fsyslog::init_with_tags(&["scene_manager_session"]).expect("Failed to init syslog");
let scenic = connect_to_service::<ScenicMarker>()?;
let scene_manager = scene_management::FlatSceneManager::new(scenic, None, None).await?;
let width = scene_manager.display_metrics.width_in_pixels() as f32;
let height = scene_manager.display_metrics.height_in_pixels() as f32;
let position = Position { x: width / 2.0, y: height / 2.0 };
let max_position = Position { x: width, y: height };
let input_pipeline = InputPipeline::new(
vec![input_device::InputDeviceType::Mouse],
vec![Box::new(SimpleCursor { position, max_position, scene_manager })],
)
.await
.context("Failed to create InputPipeline.")?;
input_pipeline.handle_input_events().await;
Ok(())
}
#[cfg(test)]
mod tests {
#[test]
fn noop_test() {
println!("Don't panic!(), you've got this!");
}
}