Skip to main content

incular_platform/
pointer.rs

1use std::fmt;
2
3use incular_core::{PointerDeviceKind, PointerPhase, PointerSampleMetadata};
4
5/// Native device details that enrich a Winit pointer sample without changing
6/// its logical contact identity or phase. This is used only when an OS adapter
7/// can supply semantics Winit intentionally omits (for example Win32 pen kind,
8/// tilt, and eraser state).
9#[derive(Clone, Copy, Debug, PartialEq)]
10pub struct NativePointerSample {
11    /// Backend-local opaque physical-device token when available. This must
12    /// never contain a raw native handle. Shared desktop coordination remaps
13    /// the token into the same process-local ID namespace used for Winit
14    /// devices before a portable [`incular_core::InputEvent`] is emitted.
15    /// `None` preserves the stable Winit device ID rather than manufacturing
16    /// one.
17    pub device: Option<u64>,
18    pub kind: PointerDeviceKind,
19    pub sample: PointerSampleMetadata,
20    /// Native contact state when the device distinguishes hover from contact.
21    /// `None` preserves the ordinary Winit touch semantics.
22    pub in_contact: Option<bool>,
23}
24
25/// Portable metadata attached to one native pointer sample before its physical
26/// position is normalized into logical window coordinates.
27#[derive(Clone, Copy, Debug, PartialEq)]
28pub struct PointerMetadata {
29    pub pointer: u64,
30    pub device: u64,
31    pub kind: PointerDeviceKind,
32    pub buttons: u32,
33    pub button: Option<u32>,
34    pub sample: PointerSampleMetadata,
35    pub phase: PointerPhase,
36}
37
38/// Native cursor grab policy for one window.
39#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
40pub enum CursorGrabMode {
41    /// Release any pointer confinement or lock owned by the window.
42    #[default]
43    None,
44    /// Keep the pointer inside the window while preserving absolute motion.
45    Confined,
46    /// Lock the pointer for relative-motion style interaction.
47    Locked,
48}
49
50/// Finite logical cursor position relative to a window's client area.
51///
52/// The validated wrapper prevents NaN/infinity from reaching native APIs whose
53/// integer/physical conversion behavior is platform-dependent.
54#[derive(Clone, Copy, Debug, PartialEq)]
55pub struct LogicalWindowPosition {
56    x: f64,
57    y: f64,
58}
59
60impl LogicalWindowPosition {
61    pub fn new(x: f64, y: f64) -> Result<Self, LogicalWindowPositionError> {
62        if !x.is_finite() || !y.is_finite() {
63            return Err(LogicalWindowPositionError);
64        }
65        Ok(Self { x, y })
66    }
67
68    #[must_use]
69    pub const fn x(self) -> f64 {
70        self.x
71    }
72
73    #[must_use]
74    pub const fn y(self) -> f64 {
75        self.y
76    }
77}
78
79#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
80pub struct LogicalWindowPositionError;
81
82impl fmt::Display for LogicalWindowPositionError {
83    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
84        formatter.write_str("logical window position must contain finite coordinates")
85    }
86}
87
88impl std::error::Error for LogicalWindowPositionError {}