From 1c9e3fe9039b266969cb3c7cb1985efaf6afd6c6 Mon Sep 17 00:00:00 2001 From: Poly Date: Wed, 30 Jun 2021 16:58:23 +0200 Subject: [PATCH] input: Add tablet events --- Cargo.toml | 4 +- anvil/src/input_handler.rs | 4 +- src/backend/input.rs | 61 +++++- src/backend/input/tablet.rs | 361 +++++++++++++++++++++++++++++++++ src/backend/libinput.rs | 45 +++- src/backend/libinput/tablet.rs | 188 +++++++++++++++++ src/backend/winit.rs | 30 ++- 7 files changed, 673 insertions(+), 20 deletions(-) create mode 100644 src/backend/input/tablet.rs create mode 100644 src/backend/libinput/tablet.rs diff --git a/Cargo.toml b/Cargo.toml index b48ca8d..5c96f88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ drm-fourcc = "^2.1.1" drm = { version = "0.4.0", optional = true } drm-ffi = { version = "0.1.0", optional = true } gbm = { version = "0.6.0", optional = true, default-features = false, features = ["drm-support"] } -input = { version = "0.5", default-features = false, optional = true } +input = { version = "0.5", default-features = false, features=["libinput_1_14"], optional = true } image = { version = "0.23.14", default-features = false, optional = true } lazy_static = "1" libc = "0.2.70" @@ -57,7 +57,7 @@ backend_gbm = ["gbm"] backend_egl = ["gl_generator"] backend_libinput = ["input"] backend_session = [] -backend_udev = ["udev"] +backend_udev = ["udev", "input/udev"] backend_session_logind = ["dbus", "backend_session", "pkg-config"] backend_session_elogind = ["backend_session_logind"] backend_session_libseat = ["backend_session", "libseat"] diff --git a/anvil/src/input_handler.rs b/anvil/src/input_handler.rs index 2a2b803..284f62a 100644 --- a/anvil/src/input_handler.rs +++ b/anvil/src/input_handler.rs @@ -81,7 +81,7 @@ impl AnvilState { input::MouseButton::Other(b) => b as u32, }; let state = match evt.state() { - input::MouseButtonState::Pressed => { + input::ButtonState::Pressed => { // change the keyboard focus unless the pointer is grabbed if !self.pointer.is_grabbed() { let under = self @@ -93,7 +93,7 @@ impl AnvilState { } wl_pointer::ButtonState::Pressed } - input::MouseButtonState::Released => wl_pointer::ButtonState::Released, + input::ButtonState::Released => wl_pointer::ButtonState::Released, }; self.pointer.button(button, state, serial, evt.time()); } diff --git a/src/backend/input.rs b/src/backend/input.rs index 91091ac..29911da 100644 --- a/src/backend/input.rs +++ b/src/backend/input.rs @@ -1,6 +1,13 @@ //! Common traits for input backends to receive input from. -use std::error::Error; +use std::{error::Error, path::PathBuf}; + +mod tablet; + +pub use tablet::{ + ProximityState, TabletToolAxisEvent, TabletToolButtonEvent, TabletToolCapabilitys, TabletToolDescriptor, + TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TabletToolType, +}; /// Trait for generic functions every input device does provide pub trait Device: PartialEq + Eq + std::hash::Hash { @@ -12,6 +19,17 @@ pub trait Device: PartialEq + Eq + std::hash::Hash { fn name(&self) -> String; /// Test if this device has a specific capability fn has_capability(&self, capability: DeviceCapability) -> bool; + + /// Get the product ID for this device. + fn id_product(&self) -> Option; + + /// Get the vendor ID for this device. + fn id_vendor(&self) -> Option; + + /// Returns the syspath of the device. + /// + /// The path is an absolute path and includes the sys mount point. + fn syspath(&self) -> Option; } /// Set of input types a device may provide @@ -105,9 +123,9 @@ pub enum MouseButton { Other(u8), } -/// State of a button on a mouse. Either pressed or released +/// State of a button on a pointer device, like mouse or tablet tool. Either pressed or released #[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum MouseButtonState { +pub enum ButtonState { /// Button is released Released, /// Button is pressed @@ -119,7 +137,7 @@ pub trait PointerButtonEvent: Event { /// Pressed button of the event fn button(&self) -> MouseButton; /// State of the button - fn state(&self) -> MouseButtonState; + fn state(&self) -> ButtonState; } impl PointerButtonEvent for UnusedEvent { @@ -127,7 +145,7 @@ impl PointerButtonEvent for UnusedEvent { match *self {} } - fn state(&self) -> MouseButtonState { + fn state(&self) -> ButtonState { match *self {} } } @@ -481,6 +499,14 @@ pub trait InputBackend: Sized { type TouchCancelEvent: TouchCancelEvent; /// Type representing touch frame events type TouchFrameEvent: TouchFrameEvent; + /// Type representing axis events on tablet devices + type TabletToolAxisEvent: TabletToolAxisEvent; + /// Type representing proximity events on tablet devices + type TabletToolProximityEvent: TabletToolProximityEvent; + /// Type representing tip events on tablet devices + type TabletToolTipEvent: TabletToolTipEvent; + /// Type representing button events on tablet tool devices + type TabletToolButtonEvent: TabletToolButtonEvent; /// Special events that are custom to this backend type SpecialEvent; @@ -557,6 +583,31 @@ pub enum InputEvent { /// The touch frame event event: B::TouchFrameEvent, }, + + /// A tablet tool axis was emited + TabletToolAxis { + /// The tablet tool axis event + event: B::TabletToolAxisEvent, + }, + + /// A tablet tool proximity was emited + TabletToolProximity { + /// The tablet tool proximity event + event: B::TabletToolProximityEvent, + }, + + /// A tablet tool tip event was emited + TabletToolTip { + /// The tablet tool axis event + event: B::TabletToolTipEvent, + }, + + /// A tablet tool button was pressed or released + TabletToolButton { + /// The pointer button event + event: B::TabletToolButtonEvent, + }, + /// Special event specific of this backend Special(B::SpecialEvent), } diff --git a/src/backend/input/tablet.rs b/src/backend/input/tablet.rs new file mode 100644 index 0000000..4ebcb33 --- /dev/null +++ b/src/backend/input/tablet.rs @@ -0,0 +1,361 @@ +use super::{ButtonState, Event, InputBackend, UnusedEvent}; + +/// Description of physical tablet tool +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct TabletToolDescriptor { + /// The tool type is the high-level type of the tool and usually decides the interaction expected from this tool. + pub tool_type: TabletToolType, + /// Unique hardware serial number of the tool + pub hardware_serial: u64, + /// Hardware id in Wacom’s format + pub hardware_id_wacom: u64, + /// Tool capability + /// Notifies the client of any capabilities of this tool, beyond the main set of x/y axes and tip up/down detection + pub capabilitys: TabletToolCapabilitys, +} + +/// Describes the physical type of a tool. The physical type of a tool generally defines its base usage. +#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] +pub enum TabletToolType { + /// A generic pen. + Pen, + /// Eraser + Eraser, + /// A paintbrush-like tool. + Brush, + /// Physical drawing tool, e.g. Wacom Inking Pen + Pencil, + /// An airbrush-like tool. + Airbrush, + /// A mouse bound to the tablet. + Mouse, + /// A mouse tool with a lens. + Lens, + /// A rotary device with positional and rotation data. + Totem, +} + +/// Describes extra capabilities on a tablet. +/// +/// Any tool must provide x and y values, extra axes are device-specific. +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct TabletToolCapabilitys { + /// Tilt axes + pub tilt: bool, + /// Pressure axis + pub pressure: bool, + /// Distance axis + pub distance: bool, + /// Z-rotation axis + pub rotation: bool, + /// Slider axis + pub slider: bool, + /// Wheel axis + pub wheel: bool, +} + +/// Tablet tool event +pub trait TabletToolEvent { + /// Get tablet tool that caused this event + fn tool(&self) -> TabletToolDescriptor; + + /// Delta between the last and new pointer device position interpreted as pixel movement + fn delta(&self) -> (f64, f64) { + (self.delta_x(), self.delta_y()) + } + + /// Tool position in the device's native coordinate space + fn position(&self) -> (f64, f64) { + (self.x(), self.y()) + } + + /// Tool position converted into the target coordinate space. + fn position_transformed(&self, coordinate_space: (u32, u32)) -> (f64, f64) { + ( + self.x_transformed(coordinate_space.0), + self.y_transformed(coordinate_space.1), + ) + } + + /// Returns the current tilt along the (X,Y) axis of the tablet's current logical + /// orientation, in degrees off the tablet's z axis. + /// + /// That is, if the tool is perfectly orthogonal to the tablet, the tilt angle is 0. + /// When the top tilts towards the logical top/left of the tablet, the x/y tilt + /// angles are negative, if the top tilts towards the logical bottom/right of the + /// tablet, the x/y tilt angles are positive. + /// + /// If this axis does not exist on the current tool, this function returns (0,0). + fn tilt(&self) -> (f64, f64) { + (self.tilt_x(), self.tilt_y()) + } + + /// Check if the tilt was updated in this event. + fn tilt_has_changed(&self) -> bool { + self.tilt_x_has_changed() || self.tilt_y_has_changed() + } + + /// Delta on the x axis between the last and new pointer device position interpreted as pixel movement + fn delta_x(&self) -> f64; + /// Delta on the y axis between the last and new pointer device position interpreted as pixel movement + fn delta_y(&self) -> f64; + + /// Returns the x coordinate of the tablet tool, in mm from the top left corner of the tablet in its current logical orientation. + fn x(&self) -> f64; + /// Returns the y coordinate of the tablet tool, in mm from the top left corner of the tablet in its current logical orientation. + fn y(&self) -> f64; + + /// Return the current absolute X coordinate of the tablet tool event, transformed to screen coordinates. + fn x_transformed(&self, width: u32) -> f64; + /// Return the current absolute Y coordinate of the tablet tool event, transformed to screen coordinates. + fn y_transformed(&self, height: u32) -> f64; + + /// Returns the current pressure being applied on the tool in use, normalized to the range [0, 1]. + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn distance(&self) -> f64; + + /// Check if the distance axis was updated in this event. + fn distance_has_changed(&self) -> bool; + + /// Returns the current distance from the tablet's sensor, normalized to the range [0, 1] + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn pressure(&self) -> f64; + + /// Check if the pressure axis was updated in this event. + fn pressure_has_changed(&self) -> bool; + + /// Returns the current position of the slider on the tool, normalized to the range + /// [-1, 1]. + /// + /// The logical zero is the neutral position of the slider, or the logical center of + /// the axis. This axis is available on e.g. the Wacom Airbrush. + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn slider_position(&self) -> f64; + + /// Check if the slider axis was updated in this event. + fn slider_has_changed(&self) -> bool; + + /// Returns the current tilt along the X axis of the tablet's current logical + /// orientation, in degrees off the tablet's z axis. + /// + /// That is, if the tool is perfectly orthogonal to the tablet, the tilt angle is 0. + /// When the top tilts towards the logical top/left of the tablet, the x/y tilt + /// angles are negative, if the top tilts towards the logical bottom/right of the + /// tablet, the x/y tilt angles are positive. + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn tilt_x(&self) -> f64; + + /// Check if the tilt x axis was updated in this event. + fn tilt_x_has_changed(&self) -> bool; + + /// Returns the current tilt along the Y axis of the tablet's current logical + /// orientation, in degrees off the tablet's z axis. + /// + /// That is, if the tool is perfectly orthogonal to the tablet, the tilt angle is 0. + /// When the top tilts towards the logical top/left of the tablet, the x/y tilt + /// angles are negative, if the top tilts towards the logical bottom/right of the + /// tablet, the x/y tilt angles are positive. + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn tilt_y(&self) -> f64; + + /// Check if the tilt y axis was updated in this event. + fn tilt_y_has_changed(&self) -> bool; + + /// Returns the current z rotation of the tool in degrees, clockwise from the tool's logical neutral position. + /// + /// For tools of type Mouse and Lens the logical neutral position is pointing to the current logical north of the tablet. For tools of type Brush, the logical neutral position is with the buttons pointing up. + /// + /// If this axis does not exist on the current tool, this function returns 0. + fn rotation(&self) -> f64; + + /// Check if the z-rotation axis was updated in this event. + fn rotation_has_changed(&self) -> bool; + + /// Return the delta for the wheel in degrees. + fn wheel_delta(&self) -> f64; + /// Return the delta for the wheel in discrete steps (e.g. wheel clicks). + fn wheel_delta_discrete(&self) -> i32; + /// Check if the wheel axis was updated in this event. + fn wheel_has_changed(&self) -> bool; +} + +impl TabletToolEvent for UnusedEvent { + fn tool(&self) -> TabletToolDescriptor { + match *self {} + } + fn delta_x(&self) -> f64 { + match *self {} + } + fn delta_y(&self) -> f64 { + match *self {} + } + fn x(&self) -> f64 { + match *self {} + } + fn y(&self) -> f64 { + match *self {} + } + fn x_transformed(&self, _width: u32) -> f64 { + match *self {} + } + fn y_transformed(&self, _height: u32) -> f64 { + match *self {} + } + fn distance(&self) -> f64 { + match *self {} + } + fn distance_has_changed(&self) -> bool { + match *self {} + } + fn pressure(&self) -> f64 { + match *self {} + } + fn pressure_has_changed(&self) -> bool { + match *self {} + } + fn slider_position(&self) -> f64 { + match *self {} + } + fn slider_has_changed(&self) -> bool { + match *self {} + } + fn tilt_x(&self) -> f64 { + match *self {} + } + fn tilt_x_has_changed(&self) -> bool { + match *self {} + } + fn tilt_y(&self) -> f64 { + match *self {} + } + fn tilt_y_has_changed(&self) -> bool { + match *self {} + } + fn rotation(&self) -> f64 { + match *self {} + } + fn rotation_has_changed(&self) -> bool { + match *self {} + } + fn wheel_delta(&self) -> f64 { + match *self {} + } + fn wheel_delta_discrete(&self) -> i32 { + match *self {} + } + fn wheel_has_changed(&self) -> bool { + match *self {} + } +} + +/// Trait for axis tablet tool events. +pub trait TabletToolAxisEvent: TabletToolEvent + Event {} + +impl TabletToolAxisEvent for UnusedEvent {} + +/// The state of proximity for a tool on a device. +/// +/// The proximity of a tool is a binary state signalling whether the tool is within a +/// detectable distance of the tablet device. A tool that is out of proximity cannot +/// generate events. +/// +/// On some hardware a tool goes out of proximity when it ceases to touch the surface. On /// other hardware, the tool is still detectable within a short distance (a few cm) off +/// the surface. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum ProximityState { + /// Out of proximity + Out, + /// In proximity + In, +} + +/// Trait for tablet tool proximity events. +pub trait TabletToolProximityEvent: TabletToolEvent + Event { + /// Returns the new proximity state of a tool from a proximity event. + /// + /// Used to check whether or not a tool came in or out of proximity during an + /// `TabletToolProximityEvent`. + /// + /// See [Handling of proximity events](https://wayland.freedesktop.org/libinput/doc/latest/tablet-support.html#tablet-fake-proximity) + /// for recommendations on proximity handling. + fn state(&self) -> ProximityState; +} + +impl TabletToolProximityEvent for UnusedEvent { + fn state(&self) -> ProximityState { + match *self {} + } +} + +/// The tip contact state for a tool on a device. +/// +/// The tip contact state of a tool is a binary state signalling whether the tool is +/// touching the surface of the tablet device. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum TabletToolTipState { + /// Not touching the surface + Up, + /// Touching the surface + Down, +} + +/// Signals that a tool has come in contact with the surface of a device with the +/// `DeviceCapability::TabletTool` capability. +/// +/// On devices without distance proximity detection, the `TabletToolTipEvent` is sent +/// immediately after `TabletToolProximityEvent` for the tip down event, and +/// immediately before for the tip up event. +/// +/// The decision when a tip touches the surface is device-dependent and may be +/// derived from pressure data or other means. If the tip state is changed by axes +/// changing state, the `TabletToolTipEvent` includes the changed axes and no +/// additional axis event is sent for this state change. In other words, a caller +/// must look at both `TabletToolAxisEvent` and `TabletToolTipEvent` events to know +/// the current state of the axes. +/// +/// If a button state change occurs at the same time as a tip state change, the order +/// of events is device-dependent. +pub trait TabletToolTipEvent: TabletToolEvent + Event { + /// Returns the new tip state of a tool from a tip event. + /// + /// Used to check whether or not a tool came in contact with the tablet surface or + /// left contact with the tablet surface during an `TabletToolTipEvent`. + fn tip_state(&self) -> TabletToolTipState; +} + +impl TabletToolTipEvent for UnusedEvent { + fn tip_state(&self) -> TabletToolTipState { + match *self {} + } +} + +/// Signals that a tool has changed a logical button state on a device with the DeviceCapability::TabletTool capability. +pub trait TabletToolButtonEvent: TabletToolEvent + Event { + /// Return the button that triggered this event. + fn button(&self) -> u32; + + /// For the button of a TabletToolButtonEvent, return the total number of buttons pressed on all devices on the associated seat after the the event was triggered. + fn seat_button_count(&self) -> u32; + + /// Return the button state of the event. + fn button_state(&self) -> ButtonState; +} + +impl TabletToolButtonEvent for UnusedEvent { + fn button(&self) -> u32 { + match *self {} + } + + fn seat_button_count(&self) -> u32 { + match *self {} + } + + fn button_state(&self) -> ButtonState { + match *self {} + } +} diff --git a/src/backend/libinput.rs b/src/backend/libinput.rs index e4a5114..6ceb91b 100644 --- a/src/backend/libinput.rs +++ b/src/backend/libinput.rs @@ -14,12 +14,15 @@ use std::path::Path; use std::{ io::Error as IoError, os::unix::io::{AsRawFd, RawFd}, + path::PathBuf, }; use calloop::{EventSource, Interest, Mode, Poll, PostAction, Readiness, Token, TokenFactory}; use slog::{info, o}; +mod tablet; + // No idea if this is the same across unix platforms // Lets make this linux exclusive for now, once someone tries to build it for // any BSD-like system, they can verify if this is right and make a PR to change this. @@ -93,6 +96,22 @@ impl backend::Device for libinput::Device { fn has_capability(&self, capability: backend::DeviceCapability) -> bool { libinput::Device::has_capability(self, capability.into()) } + + fn id_product(&self) -> Option { + Some(libinput::Device::id_product(self)) + } + + fn id_vendor(&self) -> Option { + Some(libinput::Device::id_vendor(self)) + } + + fn syspath(&self) -> Option { + #[cfg(feature = "udev")] + return unsafe { libinput::Device::udev_device(self) }.map(|d| d.syspath().to_owned()); + + #[cfg(not(feature = "udev"))] + None + } } impl From for libinput::DeviceCapability { @@ -179,7 +198,7 @@ impl backend::PointerButtonEvent for event::pointer::Point } } - fn state(&self) -> backend::MouseButtonState { + fn state(&self) -> backend::ButtonState { self.button_state().into() } } @@ -355,6 +374,10 @@ impl InputBackend for LibinputInputBackend { type TouchMotionEvent = event::touch::TouchMotionEvent; type TouchCancelEvent = event::touch::TouchCancelEvent; type TouchFrameEvent = event::touch::TouchFrameEvent; + type TabletToolAxisEvent = event::tablet_tool::TabletToolAxisEvent; + type TabletToolProximityEvent = event::tablet_tool::TabletToolProximityEvent; + type TabletToolTipEvent = event::tablet_tool::TabletToolTipEvent; + type TabletToolButtonEvent = event::tablet_tool::TabletToolButtonEvent; type SpecialEvent = backend::UnusedEvent; @@ -420,6 +443,20 @@ impl InputBackend for LibinputInputBackend { callback(InputEvent::PointerButton { event: button_event }); } }, + libinput::Event::Tablet(tablet_event) => match tablet_event { + event::TabletToolEvent::Axis(event) => { + callback(InputEvent::TabletToolAxis { event }); + } + event::TabletToolEvent::Proximity(event) => { + callback(InputEvent::TabletToolProximity { event }); + } + event::TabletToolEvent::Tip(event) => { + callback(InputEvent::TabletToolTip { event }); + } + event::TabletToolEvent::Button(event) => { + callback(InputEvent::TabletToolButton { event }); + } + }, _ => {} //FIXME: What to do with the rest. } } @@ -465,11 +502,11 @@ impl From for backend::AxisSource { } } -impl From for backend::MouseButtonState { +impl From for backend::ButtonState { fn from(libinput: event::pointer::ButtonState) -> Self { match libinput { - event::pointer::ButtonState::Pressed => backend::MouseButtonState::Pressed, - event::pointer::ButtonState::Released => backend::MouseButtonState::Released, + event::pointer::ButtonState::Pressed => backend::ButtonState::Pressed, + event::pointer::ButtonState::Released => backend::ButtonState::Released, } } } diff --git a/src/backend/libinput/tablet.rs b/src/backend/libinput/tablet.rs new file mode 100644 index 0000000..fd0744d --- /dev/null +++ b/src/backend/libinput/tablet.rs @@ -0,0 +1,188 @@ +use crate::backend::input::{ + self as backend, TabletToolCapabilitys, TabletToolDescriptor, TabletToolTipState, TabletToolType, +}; + +use input as libinput; +use input::event; +use input::event::{tablet_tool, EventTrait}; + +use super::LibinputInputBackend; + +/// Marker for tablet tool events +pub trait IsTabetEvent: tablet_tool::TabletToolEventTrait + EventTrait {} + +impl IsTabetEvent for tablet_tool::TabletToolAxisEvent {} +impl IsTabetEvent for tablet_tool::TabletToolProximityEvent {} +impl IsTabetEvent for tablet_tool::TabletToolTipEvent {} +impl IsTabetEvent for tablet_tool::TabletToolButtonEvent {} + +impl backend::Event for E +where + E: IsTabetEvent, +{ + fn time(&self) -> u32 { + tablet_tool::TabletToolEventTrait::time(self) + } + + fn device(&self) -> libinput::Device { + event::EventTrait::device(self) + } +} + +impl backend::TabletToolAxisEvent for tablet_tool::TabletToolAxisEvent {} + +impl backend::TabletToolProximityEvent for tablet_tool::TabletToolProximityEvent { + fn state(&self) -> backend::ProximityState { + match tablet_tool::TabletToolProximityEvent::proximity_state(self) { + tablet_tool::ProximityState::In => backend::ProximityState::In, + tablet_tool::ProximityState::Out => backend::ProximityState::Out, + } + } +} + +impl backend::TabletToolTipEvent for tablet_tool::TabletToolTipEvent { + fn tip_state(&self) -> TabletToolTipState { + match tablet_tool::TabletToolTipEvent::tip_state(self) { + tablet_tool::TipState::Up => backend::TabletToolTipState::Up, + tablet_tool::TipState::Down => backend::TabletToolTipState::Down, + } + } +} + +impl backend::TabletToolEvent for E +where + E: IsTabetEvent + event::EventTrait, +{ + fn tool(&self) -> TabletToolDescriptor { + let tool = self.tool(); + + let tool_type = match tool.tool_type() { + tablet_tool::TabletToolType::Pen => TabletToolType::Pen, + tablet_tool::TabletToolType::Eraser => TabletToolType::Eraser, + tablet_tool::TabletToolType::Brush => TabletToolType::Brush, + tablet_tool::TabletToolType::Pencil => TabletToolType::Pencil, + tablet_tool::TabletToolType::Airbrush => TabletToolType::Airbrush, + tablet_tool::TabletToolType::Mouse => TabletToolType::Mouse, + tablet_tool::TabletToolType::Lens => TabletToolType::Lens, + tablet_tool::TabletToolType::Totem => TabletToolType::Totem, + }; + + let hardware_serial = tool.serial(); + let hardware_id_wacom = tool.tool_id(); + + let capabilitys = TabletToolCapabilitys { + tilt: tool.has_tilt(), + pressure: tool.has_pressure(), + distance: tool.has_distance(), + rotation: tool.has_rotation(), + slider: tool.has_slider(), + wheel: tool.has_wheel(), + }; + + TabletToolDescriptor { + tool_type, + hardware_serial, + hardware_id_wacom, + capabilitys, + } + } + + fn delta_x(&self) -> f64 { + tablet_tool::TabletToolEventTrait::dx(self) + } + + fn delta_y(&self) -> f64 { + tablet_tool::TabletToolEventTrait::dy(self) + } + + fn x(&self) -> f64 { + tablet_tool::TabletToolEventTrait::x(self) + } + + fn y(&self) -> f64 { + tablet_tool::TabletToolEventTrait::y(self) + } + + fn x_transformed(&self, width: u32) -> f64 { + tablet_tool::TabletToolEventTrait::x_transformed(self, width) + } + + fn y_transformed(&self, height: u32) -> f64 { + tablet_tool::TabletToolEventTrait::y_transformed(self, height) + } + + fn distance(&self) -> f64 { + tablet_tool::TabletToolEventTrait::distance(self) + } + + fn distance_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::distance_has_changed(self) + } + + fn pressure(&self) -> f64 { + tablet_tool::TabletToolEventTrait::pressure(self) + } + + fn pressure_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::pressure_has_changed(self) + } + + fn slider_position(&self) -> f64 { + tablet_tool::TabletToolEventTrait::slider_position(self) + } + + fn slider_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::slider_has_changed(self) + } + + fn tilt_x(&self) -> f64 { + tablet_tool::TabletToolEventTrait::dx(self) + } + + fn tilt_x_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::tilt_x_has_changed(self) + } + + fn tilt_y(&self) -> f64 { + tablet_tool::TabletToolEventTrait::dy(self) + } + + fn tilt_y_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::tilt_y_has_changed(self) + } + + fn rotation(&self) -> f64 { + tablet_tool::TabletToolEventTrait::rotation(self) + } + + fn rotation_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::rotation_has_changed(self) + } + + fn wheel_delta(&self) -> f64 { + tablet_tool::TabletToolEventTrait::wheel_delta(self) + } + + fn wheel_delta_discrete(&self) -> i32 { + // I have no idea why f64 is returend by this fn, in libinput's api wheel clicks are always i32 + tablet_tool::TabletToolEventTrait::wheel_delta_discrete(self) as i32 + } + + fn wheel_has_changed(&self) -> bool { + tablet_tool::TabletToolEventTrait::wheel_has_changed(self) + } +} + +impl backend::TabletToolButtonEvent for tablet_tool::TabletToolButtonEvent { + fn button(&self) -> u32 { + tablet_tool::TabletToolButtonEvent::button(&self) + } + + fn seat_button_count(&self) -> u32 { + tablet_tool::TabletToolButtonEvent::seat_button_count(&self) + } + + fn button_state(&self) -> backend::ButtonState { + tablet_tool::TabletToolButtonEvent::button_state(&self).into() + } +} diff --git a/src/backend/winit.rs b/src/backend/winit.rs index b560611..4b18f10 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -23,8 +23,8 @@ use crate::backend::egl::display::EGLDisplay; use crate::backend::{ egl::{context::GlAttributes, native, EGLContext, EGLSurface, Error as EGLError}, input::{ - Axis, AxisSource, Device, DeviceCapability, Event as BackendEvent, InputBackend, InputEvent, - KeyState, KeyboardKeyEvent, MouseButton, MouseButtonState, PointerAxisEvent, PointerButtonEvent, + Axis, AxisSource, ButtonState, Device, DeviceCapability, Event as BackendEvent, InputBackend, + InputEvent, KeyState, KeyboardKeyEvent, MouseButton, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, TouchCancelEvent, TouchDownEvent, TouchMotionEvent, TouchSlot, TouchUpEvent, UnusedEvent, }, @@ -33,7 +33,7 @@ use crate::backend::{ Bind, Renderer, Transform, Unbind, }, }; -use std::{cell::RefCell, rc::Rc, time::Instant}; +use std::{cell::RefCell, path::PathBuf, rc::Rc, time::Instant}; use wayland_egl as wegl; use winit::{ dpi::{LogicalPosition, LogicalSize, PhysicalSize}, @@ -307,6 +307,18 @@ impl Device for WinitVirtualDevice { DeviceCapability::Keyboard | DeviceCapability::Pointer | DeviceCapability::Touch ) } + + fn id_product(&self) -> Option { + None + } + + fn id_vendor(&self) -> Option { + None + } + + fn syspath(&self) -> Option { + None + } } /// Errors that may happen when driving the event loop of [`WinitInputBackend`] @@ -460,7 +472,7 @@ impl PointerButtonEvent for WinitMouseInputEvent { self.button.into() } - fn state(&self) -> MouseButtonState { + fn state(&self) -> ButtonState { self.state.into() } } @@ -619,6 +631,10 @@ impl InputBackend for WinitInputBackend { type TouchMotionEvent = WinitTouchMovedEvent; type TouchCancelEvent = WinitTouchCancelledEvent; type TouchFrameEvent = UnusedEvent; + type TabletToolAxisEvent = UnusedEvent; + type TabletToolProximityEvent = UnusedEvent; + type TabletToolTipEvent = UnusedEvent; + type TabletToolButtonEvent = UnusedEvent; type SpecialEvent = WinitEvent; @@ -846,11 +862,11 @@ impl From for KeyState { } } -impl From for MouseButtonState { +impl From for ButtonState { fn from(state: ElementState) -> Self { match state { - ElementState::Pressed => MouseButtonState::Pressed, - ElementState::Released => MouseButtonState::Released, + ElementState::Pressed => ButtonState::Pressed, + ElementState::Released => ButtonState::Released, } } }