openxr_sys/
lib.rs

1use std::{convert::TryFrom, fmt};
2
3#[macro_use]
4mod support;
5mod generated;
6pub mod loader;
7pub mod platform;
8
9#[cfg(feature = "mint")]
10mod mint_impls;
11
12pub trait Handle: Copy {
13    const NULL: Self;
14    fn into_raw(self) -> u64;
15    fn from_raw(handle: u64) -> Self;
16}
17
18// Hand-written bindings for cases which are too few or weird to bother automating
19
20wrapper! {
21    #[derive(Copy, Clone, Eq, PartialEq, Default)]
22    Bool32(u32)
23}
24pub const TRUE: Bool32 = Bool32(1);
25pub const FALSE: Bool32 = Bool32(0);
26impl fmt::Display for Bool32 {
27    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
28        (*self != FALSE).fmt(fmt)
29    }
30}
31
32impl fmt::Debug for Bool32 {
33    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
34        (*self != FALSE).fmt(fmt)
35    }
36}
37
38impl From<Bool32> for bool {
39    fn from(x: Bool32) -> Self {
40        x != FALSE
41    }
42}
43
44impl From<bool> for Bool32 {
45    fn from(x: bool) -> Self {
46        Self(x as _)
47    }
48}
49
50#[derive(Copy, Clone, Eq, PartialEq)]
51#[repr(transparent)]
52pub struct Time(i64);
53impl Time {
54    pub fn from_nanos(x: i64) -> Self {
55        Self(x)
56    }
57
58    pub fn as_nanos(self) -> i64 {
59        self.0
60    }
61}
62
63impl fmt::Debug for Time {
64    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
65        self.0.fmt(fmt)
66    }
67}
68
69impl std::ops::Sub<Time> for Time {
70    type Output = Duration;
71
72    fn sub(self, other: Time) -> Duration {
73        Duration(self.0.wrapping_sub(other.0))
74    }
75}
76
77#[derive(Copy, Clone, Default, Eq, PartialEq)]
78#[repr(transparent)]
79pub struct Duration(i64);
80impl Duration {
81    pub fn from_nanos(x: i64) -> Self {
82        Self(x)
83    }
84
85    pub fn as_nanos(self) -> i64 {
86        self.0
87    }
88}
89
90impl Duration {
91    pub const NONE: Self = Self(0);
92    pub const INFINITE: Self = Self(i64::MAX);
93    pub const MIN_HAPTIC: Self = Self(-1);
94}
95
96impl fmt::Debug for Duration {
97    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
98        std::time::Duration::from_nanos(self.0 as u64).fmt(fmt)
99    }
100}
101
102impl From<Duration> for std::time::Duration {
103    fn from(x: Duration) -> Self {
104        Self::from_nanos(x.0.unsigned_abs())
105    }
106}
107
108impl TryFrom<std::time::Duration> for Duration {
109    type Error = std::num::TryFromIntError;
110    fn try_from(x: std::time::Duration) -> std::result::Result<Self, Self::Error> {
111        Ok(Self::from_nanos(i64::try_from(x.as_nanos())?))
112    }
113}
114
115wrapper! {
116    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
117    AsyncRequestIdFB(u64)
118}
119
120wrapper! {
121    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
122    Path(u64)
123}
124
125impl Path {
126    pub const NULL: Path = Path(0);
127}
128
129wrapper! {
130    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
131    SystemId(u64)
132}
133
134impl SystemId {
135    pub const NULL: SystemId = SystemId(0);
136}
137
138wrapper! {
139    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
140    ControllerModelKeyMSFT(u64)
141}
142
143impl ControllerModelKeyMSFT {
144    pub const NULL: ControllerModelKeyMSFT = ControllerModelKeyMSFT(0);
145}
146
147wrapper! {
148    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
149    RenderModelKeyFB(u64)
150}
151
152impl RenderModelKeyFB {
153    pub const NULL: RenderModelKeyFB = RenderModelKeyFB(0);
154}
155
156wrapper! {
157    #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
158    MarkerML(u64)
159}
160
161wrapper! {
162    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
163    SpaceUserIdFB(u64)
164}
165
166wrapper! {
167    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
168    FutureEXT(u64)
169}
170
171wrapper! {
172    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
173    TrackableANDROID(u64)
174}
175
176wrapper! {
177    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
178    RenderModelIdEXT(u64)
179}
180
181wrapper! {
182    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
183    SpatialEntityIdEXT(u64)
184}
185
186wrapper! {
187    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
188    SpatialBufferIdEXT(u64)
189}
190
191wrapper! {
192    #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
193    SpatialEntityIdBD(u64)
194}
195
196wrapper! {
197    #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
198    Version(u64)
199}
200
201impl Version {
202    #[inline]
203    pub const fn new(major: u16, minor: u16, patch: u32) -> Self {
204        Self((major as u64) << 48 | (minor as u64) << 32 | patch as u64)
205    }
206
207    #[inline]
208    pub const fn major(self) -> u16 {
209        (self.0 >> 48) as u16
210    }
211
212    #[inline]
213    pub const fn minor(self) -> u16 {
214        (self.0 >> 32) as u16
215    }
216
217    #[inline]
218    pub const fn patch(self) -> u32 {
219        self.0 as u32
220    }
221}
222
223impl From<(u16, u16, u32)> for Version {
224    fn from(other: (u16, u16, u32)) -> Self {
225        Self::new(other.0, other.1, other.2)
226    }
227}
228
229impl fmt::Display for Version {
230    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
231        write!(fmt, "{}.{}.{}", self.major(), self.minor(), self.patch())
232    }
233}
234
235impl fmt::Debug for Version {
236    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
237        write!(fmt, "{}.{}.{}", self.major(), self.minor(), self.patch())
238    }
239}
240
241pub const FREQUENCY_UNSPECIFIED: f32 = 0.0;
242
243impl Quaternionf {
244    pub const IDENTITY: Quaternionf = Quaternionf {
245        x: 0.0,
246        y: 0.0,
247        z: 0.0,
248        w: 1.0,
249    };
250}
251
252impl Posef {
253    pub const IDENTITY: Posef = Posef {
254        orientation: Quaternionf::IDENTITY,
255        position: Vector3f {
256            x: 0.0,
257            y: 0.0,
258            z: 0.0,
259        },
260    };
261}
262
263pub use generated::*;
264
265impl<T> std::ops::Index<HandJointEXT> for [T] {
266    type Output = T;
267    fn index(&self, joint: HandJointEXT) -> &T {
268        &self[joint.into_raw() as usize]
269    }
270}
271
272impl<T> std::ops::IndexMut<HandJointEXT> for [T] {
273    fn index_mut(&mut self, joint: HandJointEXT) -> &mut T {
274        &mut self[joint.into_raw() as usize]
275    }
276}
277
278// Magic Leap
279#[derive(Copy, Clone, Debug)]
280#[repr(C)]
281pub struct MLCoordinateFrameUID {
282    pub data: [u64; 2],
283}
284
285// Hacky constants originating from enums
286pub const EYE_POSITION_COUNT_FB: usize = 2;