Mercurial > tablet-emu
diff src/state.rs @ 11:0193041f01d4
Split State into another module.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 01 Nov 2020 15:56:00 +0100 |
parents | |
children | d43c31aff57c |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,110 @@ +// Tablet emulator, for people who don’t own one +// Copyright © 2020 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use std::fs::File; +use std::sync::{Arc, Mutex}; + +use crate::{create_uinput_device, WIDTH, HEIGHT, input_axis_new, input_misc_new, input_key_new, input_synchronize_new, MAX_X, MAX_Y}; +use input_linux::{AbsoluteAxis, Key, MiscKind, SynchronizeKind, UInputHandle}; + +pub struct State { + dev: UInputHandle<File>, + width: f64, + height: f64, + selected_tool: Key, + pressed: bool, +} + +impl State { + pub fn new() -> std::io::Result<Arc<Mutex<State>>> { + let dev = create_uinput_device()?; + println!( + "New device at {:?} ({:?})", + dev.evdev_path()?, + dev.sys_path()? + ); + + Ok(Arc::new(Mutex::new(State { + dev, + width: WIDTH as f64, + height: HEIGHT as f64, + selected_tool: Key::ButtonToolPen, + pressed: false, + }))) + } + + pub fn set_size(&mut self, (width, height): (u32, u32)) { + self.width = width as f64; + self.height = height as f64; + } + + pub fn select_tool(&mut self, tool: Key) { + self.selected_tool = tool; + } + + pub fn press(&mut self, x: f64, y: f64) -> std::io::Result<()> { + self.pressed = true; + self.dev.write(&[ + input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / self.width) as i32), + input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / self.height) as i32), + input_axis_new(AbsoluteAxis::Z, 0), + input_axis_new(AbsoluteAxis::Wheel, 0), + input_axis_new(AbsoluteAxis::Pressure, 1024), + input_axis_new(AbsoluteAxis::Distance, 0), + input_axis_new(AbsoluteAxis::TiltX, 16), + input_axis_new(AbsoluteAxis::TiltY, 0), + input_misc_new(MiscKind::Serial, 0), + input_key_new(self.selected_tool, 1), + input_synchronize_new(SynchronizeKind::Report, 0), + ])?; + Ok(()) + } + + pub fn release(&mut self, x: f64, y: f64) -> std::io::Result<()> { + self.pressed = false; + self.dev.write(&[ + input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / self.width) as i32), + input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / self.height) as i32), + input_axis_new(AbsoluteAxis::Z, 0), + input_axis_new(AbsoluteAxis::Wheel, 0), + input_axis_new(AbsoluteAxis::Pressure, 0), + input_axis_new(AbsoluteAxis::Distance, 16), + input_axis_new(AbsoluteAxis::TiltX, 16), + input_axis_new(AbsoluteAxis::TiltY, 0), + input_misc_new(MiscKind::Serial, 0), + input_key_new(self.selected_tool, 1), + input_synchronize_new(SynchronizeKind::Report, 0), + ])?; + Ok(()) + } + + pub fn motion(&mut self, x: f64, y: f64) -> std::io::Result<()> { + self.dev.write(&[ + input_axis_new(AbsoluteAxis::X, (x * MAX_X as f64 / self.width) as i32), + input_axis_new(AbsoluteAxis::Y, (y * MAX_Y as f64 / self.height) as i32), + input_axis_new(AbsoluteAxis::Z, 0), + input_axis_new(AbsoluteAxis::Wheel, 0), + input_axis_new(AbsoluteAxis::Pressure, if self.pressed { 2048 } else { 0 }), + input_axis_new(AbsoluteAxis::Distance, if self.pressed { 0 } else { 32 }), + input_axis_new(AbsoluteAxis::TiltX, 16), + input_axis_new(AbsoluteAxis::TiltY, 0), + input_misc_new(MiscKind::Serial, 0), + input_key_new(self.selected_tool, 1), + input_synchronize_new(SynchronizeKind::Report, 0), + ])?; + Ok(()) + } +}