<NME> input.rs
<BEF> //! Input backend implementation for the X11 backend.

use super::{window_inner::WindowInner, Window, WindowTemporary};
use crate::{
    backend::input::{
        self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, KeyState,
        KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, UnusedEvent,
    },
    utils::{Logical, Size},
};
use std::sync::Weak;

/// Marker used to define the `InputBackend` types for the X11 backend.
#[derive(Debug)]
pub struct X11Input;

/// Virtual input device used by the backend to associate input events.
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct X11VirtualDevice;

impl Device for X11VirtualDevice {
    fn id(&self) -> String {
        "x11".to_owned()
    }

    fn name(&self) -> String {
        "x11 virtual input".to_owned()
    }

    fn has_capability(&self, capability: DeviceCapability) -> bool {
        matches!(
            capability,
            DeviceCapability::Keyboard | DeviceCapability::Pointer | DeviceCapability::Touch
        )
    }

    fn usb_id(&self) -> Option<(u32, u32)> {
        None
    }

    fn syspath(&self) -> Option<std::path::PathBuf> {
        None
    }
}

/// X11-Backend internal event wrapping `X11`'s types into a [`KeyboardKeyEvent`].
#[derive(Debug, Clone)]
pub struct X11KeyboardInputEvent {
    pub(crate) time: u32,
    pub(crate) key: u32,
    pub(crate) count: u32,
    pub(crate) state: KeyState,
    pub(crate) window: Weak<WindowInner>,
}

impl X11KeyboardInputEvent {
    /// Returns a temporary reference to the window belonging to this event.
    ///
    /// Returns None if the window is not alive anymore.
    pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
        self.window.upgrade().map(Window).map(WindowTemporary)
    }
}

impl input::Event<X11Input> for X11KeyboardInputEvent {
    fn time(&self) -> u32 {
        self.time
    }

    fn device(&self) -> X11VirtualDevice {
        X11VirtualDevice
    }
}

impl KeyboardKeyEvent<X11Input> for X11KeyboardInputEvent {
    fn key_code(&self) -> u32 {
        self.key
    }

    fn state(&self) -> KeyState {
        self.state
    }

    fn count(&self) -> u32 {
        self.count
    }
}

/// X11-Backend internal event wrapping `X11`'s types into a [`PointerAxisEvent`]
#[derive(Debug, Clone)]
pub struct X11MouseWheelEvent {
    pub(crate) time: u32,
    pub(crate) axis: Axis,
    pub(crate) amount: f64,
    pub(crate) window: Weak<WindowInner>,
}

impl X11MouseWheelEvent {
    /// Returns a temporary reference to the window belonging to this event.
    ///
    /// Returns None if the window is not alive anymore.
    pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
        self.window.upgrade().map(Window).map(WindowTemporary)
    }
}

impl input::Event<X11Input> for X11MouseWheelEvent {
    fn time(&self) -> u32 {
        self.time
    }

    fn device(&self) -> X11VirtualDevice {
        X11VirtualDevice
    }
}

impl PointerAxisEvent<X11Input> for X11MouseWheelEvent {
    fn amount(&self, _axis: Axis) -> Option<f64> {
        None
    }

    fn amount_discrete(&self, axis: Axis) -> Option<f64> {
        if self.axis == axis {
            Some(self.amount)
        } else {
            Some(0.0)
        }
    }

    fn source(&self) -> AxisSource {
        // X11 seems to act within the scope of individual rachets of a scroll wheel.
        AxisSource::Wheel
    }
}

/// X11-Backend internal event wrapping `X11`'s types into a [`PointerButtonEvent`]
#[derive(Debug, Clone)]
pub struct X11MouseInputEvent {
    pub(crate) time: u32,
    pub(crate) raw: u32,
    pub(crate) state: ButtonState,
    pub(crate) window: Weak<WindowInner>,
}

impl X11MouseInputEvent {
    /// Returns a temporary reference to the window belonging to this event.
    ///
    /// Returns None if the window is not alive anymore.
    pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
        self.window.upgrade().map(Window).map(WindowTemporary)
    }
}

impl input::Event<X11Input> for X11MouseInputEvent {
    fn time(&self) -> u32 {
        self.time
    }

    fn device(&self) -> X11VirtualDevice {
        X11VirtualDevice
    }
}

impl PointerButtonEvent<X11Input> for X11MouseInputEvent {
    fn button_code(&self) -> u32 {
        input::xorg_mouse_to_libinput(self.raw)
    }

    fn state(&self) -> ButtonState {
        self.state
    }
}

/// X11-Backend internal event wrapping `X11`'s types into a [`PointerMotionAbsoluteEvent`]
#[derive(Debug, Clone)]
pub struct X11MouseMovedEvent {
    pub(crate) time: u32,
    pub(crate) x: f64,
    pub(crate) y: f64,
    pub(crate) size: Size<u16, Logical>,
    pub(crate) window: Weak<WindowInner>,
}

impl X11MouseMovedEvent {
    /// Returns a temporary reference to the window belonging to this event.
    ///
    /// Returns None if the window is not alive anymore.
    pub fn window(&self) -> Option<impl AsRef<Window> + '_> {
        self.window.upgrade().map(Window).map(WindowTemporary)
    }
}

impl input::Event<X11Input> for X11MouseMovedEvent {
    fn time(&self) -> u32 {
        self.time
    }

    fn device(&self) -> X11VirtualDevice {
        X11VirtualDevice
    }
}

impl PointerMotionAbsoluteEvent<X11Input> for X11MouseMovedEvent {
    fn x(&self) -> f64 {
        self.x
    }

    fn y(&self) -> f64 {
        self.y
    }

    fn x_transformed(&self, width: i32) -> f64 {
        f64::max(self.x * width as f64 / self.size.w as f64, 0.0)
    }

    fn y_transformed(&self, height: i32) -> f64 {
        f64::max(self.y * height as f64 / self.size.h as f64, 0.0)
    }
}

impl InputBackend for X11Input {
    type Device = X11VirtualDevice;
    type KeyboardKeyEvent = X11KeyboardInputEvent;
    type PointerAxisEvent = X11MouseWheelEvent;
    type PointerButtonEvent = X11MouseInputEvent;

    type PointerMotionEvent = UnusedEvent;

    type PointerMotionAbsoluteEvent = X11MouseMovedEvent;

    type TouchDownEvent = UnusedEvent;
    type TouchUpEvent = UnusedEvent;
    type TouchMotionEvent = UnusedEvent;
    type TouchCancelEvent = UnusedEvent;
    type TouchFrameEvent = UnusedEvent;
    type TabletToolAxisEvent = UnusedEvent;
    type TabletToolProximityEvent = UnusedEvent;
    type TabletToolTipEvent = UnusedEvent;
    type TabletToolButtonEvent = UnusedEvent;

    type SpecialEvent = UnusedEvent;
}

<MSG> Merge pull request #502 from chrisduerr/shared_trait

Move shared input event functions to common traits
<DFF> @@ -3,8 +3,9 @@
 use super::{window_inner::WindowInner, Window, WindowTemporary};
 use crate::{
     backend::input::{
-        self, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend, KeyState,
-        KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent, UnusedEvent,
+        self, AbsolutePositionEvent, Axis, AxisSource, ButtonState, Device, DeviceCapability, InputBackend,
+        KeyState, KeyboardKeyEvent, PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
+        UnusedEvent,
     },
     utils::{Logical, Size},
 };
@@ -200,7 +201,8 @@ impl input::Event<X11Input> for X11MouseMovedEvent {
     }
 }
 
-impl PointerMotionAbsoluteEvent<X11Input> for X11MouseMovedEvent {
+impl PointerMotionAbsoluteEvent<X11Input> for X11MouseMovedEvent {}
+impl AbsolutePositionEvent<X11Input> for X11MouseMovedEvent {
     fn x(&self) -> f64 {
         self.x
     }

Merge pull request #502 from chrisduerr/shared_trait