Skip to main content

incular_platform/
pointer.rs

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