# HG changeset patch # User Emmanuel Gil Peyrot # Date 1604242860 -3600 # Node ID d43c31aff57cc845b292cba3930e343c68238986 # Parent 0193041f01d490fc9d6dbaa6581c059fe553ffda Split uinput helpers into another module. diff --git a/src/main.rs b/src/main.rs --- a/src/main.rs +++ b/src/main.rs @@ -19,15 +19,11 @@ use glib::clone; use gtk::prelude::*; use std::env::args; -use std::fs::{File, OpenOptions}; use std::io::ErrorKind; use std::sync::Arc; +use input_linux::Key; -use input_linux::{ - sys::input_event, sys::timeval, AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, - InputId, InputProperty, Key, MiscKind, SynchronizeKind, UInputHandle, -}; - +mod uinput; mod state; use state::State; @@ -37,180 +33,6 @@ const HEIGHT: i32 = 180; const MAX_X: i32 = 69920; const MAX_Y: i32 = 39980; -fn create_uinput_device() -> std::io::Result> { - let file = OpenOptions::new().write(true).open("/dev/uinput")?; - let dev = UInputHandle::new(file); - - dev.set_evbit(EventKind::Synchronize)?; - dev.set_evbit(EventKind::Key)?; - dev.set_evbit(EventKind::Absolute)?; - dev.set_evbit(EventKind::Misc)?; - dev.set_keybit(Key::ButtonToolPen)?; - dev.set_keybit(Key::ButtonToolRubber)?; - dev.set_keybit(Key::ButtonToolBrush)?; - dev.set_keybit(Key::ButtonToolPencil)?; - dev.set_keybit(Key::ButtonToolAirbrush)?; - dev.set_keybit(Key::ButtonTouch)?; - dev.set_keybit(Key::ButtonStylus)?; - dev.set_keybit(Key::ButtonStylus2)?; - dev.set_keybit(Key::ButtonStylus3)?; - dev.set_mscbit(MiscKind::Serial)?; - dev.set_propbit(InputProperty::Direct)?; - - dev.set_absbit(AbsoluteAxis::X)?; - dev.set_absbit(AbsoluteAxis::Y)?; - dev.set_absbit(AbsoluteAxis::Z)?; - dev.set_absbit(AbsoluteAxis::Wheel)?; - dev.set_absbit(AbsoluteAxis::Pressure)?; - dev.set_absbit(AbsoluteAxis::Distance)?; - dev.set_absbit(AbsoluteAxis::TiltX)?; - dev.set_absbit(AbsoluteAxis::TiltY)?; - dev.set_absbit(AbsoluteAxis::Misc)?; - - let id = InputId { - bustype: 3, - vendor: 0x56a, - product: 0x350, - version: 0xb, - }; - - let x = AbsoluteInfoSetup { - axis: AbsoluteAxis::X, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: MAX_X, - fuzz: 0, - flat: 0, - resolution: 200, - }, - }; - let y = AbsoluteInfoSetup { - axis: AbsoluteAxis::Y, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: MAX_Y, - fuzz: 0, - flat: 0, - resolution: 200, - }, - }; - let z = AbsoluteInfoSetup { - axis: AbsoluteAxis::Z, - info: AbsoluteInfo { - value: 0, - minimum: -900, - maximum: 899, - fuzz: 0, - flat: 0, - resolution: 287, - }, - }; - let wheel = AbsoluteInfoSetup { - axis: AbsoluteAxis::Wheel, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: 2047, - fuzz: 0, - flat: 0, - resolution: 0, - }, - }; - let pressure = AbsoluteInfoSetup { - axis: AbsoluteAxis::Pressure, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: 8196, - fuzz: 0, - flat: 0, - resolution: 0, - }, - }; - let distance = AbsoluteInfoSetup { - axis: AbsoluteAxis::Distance, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: 63, - fuzz: 0, - flat: 0, - resolution: 0, - }, - }; - let tilt_x = AbsoluteInfoSetup { - axis: AbsoluteAxis::TiltX, - info: AbsoluteInfo { - value: 0, - minimum: -64, - maximum: 63, - fuzz: 0, - flat: 0, - resolution: 57, - }, - }; - let tilt_y = AbsoluteInfoSetup { - axis: AbsoluteAxis::TiltY, - info: AbsoluteInfo { - value: 0, - minimum: -64, - maximum: 63, - fuzz: 0, - flat: 0, - resolution: 57, - }, - }; - let misc = AbsoluteInfoSetup { - axis: AbsoluteAxis::Misc, - info: AbsoluteInfo { - value: 0, - minimum: 0, - maximum: 0, - fuzz: 0, - flat: 0, - resolution: 0, - }, - }; - - dev.create( - &id, - b"TabletEmu", - 0, - &[x, y, z, wheel, pressure, distance, tilt_x, tilt_y, misc], - )?; - Ok(dev) -} - -fn input_event_new(type_: EventKind, code: u16, value: i32) -> input_event { - input_event { - time: timeval { - tv_sec: 0, - tv_usec: 0, - }, - type_: type_ as u16, - code, - value, - } -} - -fn input_axis_new(code: AbsoluteAxis, value: i32) -> input_event { - input_event_new(EventKind::Absolute, code as u16, value) -} - -fn input_key_new(code: Key, value: i32) -> input_event { - input_event_new(EventKind::Key, code as u16, value) -} - -fn input_misc_new(code: MiscKind, value: i32) -> input_event { - input_event_new(EventKind::Misc, code as u16, value) -} - -fn input_synchronize_new(code: SynchronizeKind, value: i32) -> input_event { - input_event_new(EventKind::Synchronize, code as u16, value) -} - fn build_main_menu(application: >k::Application) { let quit = gio::SimpleAction::new("quit", None); application.set_accels_for_action("app.quit", &["q"]); diff --git a/src/state.rs b/src/state.rs --- a/src/state.rs +++ b/src/state.rs @@ -17,8 +17,9 @@ 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}; +use crate::{WIDTH, HEIGHT, MAX_X, MAX_Y}; +use crate::uinput::{create_uinput_device, input_axis_new, input_misc_new, input_key_new, input_synchronize_new}; pub struct State { dev: UInputHandle, diff --git a/src/uinput.rs b/src/uinput.rs new file mode 100644 --- /dev/null +++ b/src/uinput.rs @@ -0,0 +1,196 @@ +// Tablet emulator, for people who don’t own one +// Copyright © 2020 Emmanuel Gil Peyrot +// +// 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 . + +use std::fs::{File, OpenOptions}; +use crate::{MAX_X, MAX_Y}; +use input_linux::{ + sys::input_event, sys::timeval, AbsoluteAxis, AbsoluteInfo, AbsoluteInfoSetup, EventKind, + InputId, InputProperty, Key, MiscKind, SynchronizeKind, UInputHandle, +}; + +pub fn create_uinput_device() -> std::io::Result> { + let file = OpenOptions::new().write(true).open("/dev/uinput")?; + let dev = UInputHandle::new(file); + + dev.set_evbit(EventKind::Synchronize)?; + dev.set_evbit(EventKind::Key)?; + dev.set_evbit(EventKind::Absolute)?; + dev.set_evbit(EventKind::Misc)?; + dev.set_keybit(Key::ButtonToolPen)?; + dev.set_keybit(Key::ButtonToolRubber)?; + dev.set_keybit(Key::ButtonToolBrush)?; + dev.set_keybit(Key::ButtonToolPencil)?; + dev.set_keybit(Key::ButtonToolAirbrush)?; + dev.set_keybit(Key::ButtonTouch)?; + dev.set_keybit(Key::ButtonStylus)?; + dev.set_keybit(Key::ButtonStylus2)?; + dev.set_keybit(Key::ButtonStylus3)?; + dev.set_mscbit(MiscKind::Serial)?; + dev.set_propbit(InputProperty::Direct)?; + + dev.set_absbit(AbsoluteAxis::X)?; + dev.set_absbit(AbsoluteAxis::Y)?; + dev.set_absbit(AbsoluteAxis::Z)?; + dev.set_absbit(AbsoluteAxis::Wheel)?; + dev.set_absbit(AbsoluteAxis::Pressure)?; + dev.set_absbit(AbsoluteAxis::Distance)?; + dev.set_absbit(AbsoluteAxis::TiltX)?; + dev.set_absbit(AbsoluteAxis::TiltY)?; + dev.set_absbit(AbsoluteAxis::Misc)?; + + let id = InputId { + bustype: 3, + vendor: 0x56a, + product: 0x350, + version: 0xb, + }; + + let x = AbsoluteInfoSetup { + axis: AbsoluteAxis::X, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: MAX_X, + fuzz: 0, + flat: 0, + resolution: 200, + }, + }; + let y = AbsoluteInfoSetup { + axis: AbsoluteAxis::Y, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: MAX_Y, + fuzz: 0, + flat: 0, + resolution: 200, + }, + }; + let z = AbsoluteInfoSetup { + axis: AbsoluteAxis::Z, + info: AbsoluteInfo { + value: 0, + minimum: -900, + maximum: 899, + fuzz: 0, + flat: 0, + resolution: 287, + }, + }; + let wheel = AbsoluteInfoSetup { + axis: AbsoluteAxis::Wheel, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: 2047, + fuzz: 0, + flat: 0, + resolution: 0, + }, + }; + let pressure = AbsoluteInfoSetup { + axis: AbsoluteAxis::Pressure, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: 8196, + fuzz: 0, + flat: 0, + resolution: 0, + }, + }; + let distance = AbsoluteInfoSetup { + axis: AbsoluteAxis::Distance, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: 63, + fuzz: 0, + flat: 0, + resolution: 0, + }, + }; + let tilt_x = AbsoluteInfoSetup { + axis: AbsoluteAxis::TiltX, + info: AbsoluteInfo { + value: 0, + minimum: -64, + maximum: 63, + fuzz: 0, + flat: 0, + resolution: 57, + }, + }; + let tilt_y = AbsoluteInfoSetup { + axis: AbsoluteAxis::TiltY, + info: AbsoluteInfo { + value: 0, + minimum: -64, + maximum: 63, + fuzz: 0, + flat: 0, + resolution: 57, + }, + }; + let misc = AbsoluteInfoSetup { + axis: AbsoluteAxis::Misc, + info: AbsoluteInfo { + value: 0, + minimum: 0, + maximum: 0, + fuzz: 0, + flat: 0, + resolution: 0, + }, + }; + + dev.create( + &id, + b"TabletEmu", + 0, + &[x, y, z, wheel, pressure, distance, tilt_x, tilt_y, misc], + )?; + Ok(dev) +} + +fn input_event_new(type_: EventKind, code: u16, value: i32) -> input_event { + input_event { + time: timeval { + tv_sec: 0, + tv_usec: 0, + }, + type_: type_ as u16, + code, + value, + } +} + +pub fn input_axis_new(code: AbsoluteAxis, value: i32) -> input_event { + input_event_new(EventKind::Absolute, code as u16, value) +} + +pub fn input_key_new(code: Key, value: i32) -> input_event { + input_event_new(EventKind::Key, code as u16, value) +} + +pub fn input_misc_new(code: MiscKind, value: i32) -> input_event { + input_event_new(EventKind::Misc, code as u16, value) +} + +pub fn input_synchronize_new(code: SynchronizeKind, value: i32) -> input_event { + input_event_new(EventKind::Synchronize, code as u16, value) +}