Skip to main content

input_pipeline_dso/
utils.rs

1// Copyright 2020 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// TODO(https://fxbug.dev/494333485): Delete this module in favor of using the autogenerated
6// fidl_next conversions, once available.
7
8use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
9use zx;
10
11// TODO: b/513635934 - remove this when we can move the value from wire type table.
12pub fn duplicate_wake_lease(
13    wake_lease: Option<&fidl_next::wire::fuchsia::EventPair>,
14) -> Option<zx::EventPair> {
15    wake_lease.map(|h| h.as_raw_handle()).map(|raw| {
16        // SAFETY: `raw` is a valid handle obtained from `wake_lease`, which is borrowed
17        // for the duration of this function. The `zx::Unowned` instance is created from
18        // this valid handle and does not outlive the borrow of `wake_lease`, ensuring
19        // that the handle remains valid while `Unowned` exists.
20        let unowned = unsafe { zx::Unowned::<'_, zx::EventPair>::from_raw_handle(raw) };
21        unowned.duplicate_handle(zx::Rights::SAME_RIGHTS).expect("failed to duplicate wake lease")
22    })
23}
24
25pub fn duplicate_view_ref_next(
26    view_ref: &fidl_next_fuchsia_ui_views::ViewRef,
27) -> Result<fidl_next_fuchsia_ui_views::ViewRef, fidl::Status> {
28    let handle = view_ref.reference.as_handle_ref().duplicate_handle(fidl::Rights::SAME_RIGHTS)?;
29    Ok(fidl_next_fuchsia_ui_views::ViewRef { reference: handle.into() })
30}
31
32pub fn axis_to_next(
33    axis: Option<&fidl_fuchsia_input::Axis>,
34) -> Option<fidl_next_fuchsia_input::Axis> {
35    axis.map(|a| fidl_next_fuchsia_input::Axis {
36        range: fidl_next_fuchsia_input::Range { min: a.range.min, max: a.range.max },
37        unit: fidl_next_fuchsia_input::Unit {
38            type_: a.unit.type_.into_primitive().into(),
39            exponent: a.unit.exponent,
40        },
41    })
42}
43
44pub fn axis_to_old(
45    axis: Option<&fidl_next_fuchsia_input::Axis>,
46) -> Option<fidl_fuchsia_input::Axis> {
47    axis.map(|a| fidl_fuchsia_input::Axis {
48        range: fidl_fuchsia_input::Range { min: a.range.min, max: a.range.max },
49        unit: unit_to_old(&a.unit),
50    })
51}
52
53pub fn viewport_to_next(
54    viewport: &fidl_fuchsia_ui_pointerinjector::Viewport,
55) -> fidl_next_fuchsia_ui_pointerinjector::Viewport {
56    fidl_next_fuchsia_ui_pointerinjector::Viewport {
57        extents: viewport.extents.clone(),
58        viewport_to_context_transform: viewport.viewport_to_context_transform.clone(),
59    }
60}
61
62pub fn range_to_old(range: &fidl_next_fuchsia_input::Range) -> fidl_fuchsia_input::Range {
63    fidl_fuchsia_input::Range { min: range.min, max: range.max }
64}
65
66pub fn unit_to_old(unit: &fidl_next_fuchsia_input::Unit) -> fidl_fuchsia_input::Unit {
67    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
68    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
69    // it is safe because the memory is initialized, aligned correctly, and we only
70    // perform a read operation.
71    let discriminant: u32 =
72        unsafe { *(&unit.type_ as *const fidl_next_fuchsia_input::UnitType as *const u32) };
73    fidl_fuchsia_input::Unit {
74        type_: fidl_fuchsia_input::UnitType::from_primitive_allow_unknown(discriminant),
75        exponent: unit.exponent,
76    }
77}
78
79pub fn key_to_old(key: &fidl_next_fuchsia_input::Key) -> fidl_fuchsia_input::Key {
80    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
81    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
82    // it is safe because the memory is initialized, aligned correctly, and we only
83    // perform a read operation.
84    let discriminant: u32 = unsafe { *(key as *const fidl_next_fuchsia_input::Key as *const u32) };
85    fidl_fuchsia_input::Key::from_primitive_allow_unknown(discriminant)
86}
87
88#[cfg(test)]
89pub fn key_to_next(key: &fidl_fuchsia_input::Key) -> fidl_next_fuchsia_input::Key {
90    let discriminant = key.into_primitive();
91    fidl_next_fuchsia_input::Key::from(discriminant)
92}
93
94#[cfg(test)]
95pub fn touch_button_to_next(
96    button: &fidl_fuchsia_input_report::TouchButton,
97) -> fidl_next_fuchsia_input_report::TouchButton {
98    let discriminant = button.into_primitive();
99    fidl_next_fuchsia_input_report::TouchButton::from(discriminant)
100}
101
102pub fn consumer_control_button_to_old(
103    button: &fidl_next_fuchsia_input::ConsumerControlButton,
104) -> fidl_fuchsia_input::ConsumerControlButton {
105    // SAFETY: The `fidl_next` generated enum is representation-compatible with `u32`
106    // (typically `#[repr(u32)]`). Casting the pointer to `*const u32` and dereferencing
107    // it is safe because the memory is initialized, aligned correctly, and we only
108    // perform a read operation.
109    let discriminant: u32 =
110        unsafe { *(button as *const fidl_next_fuchsia_input::ConsumerControlButton as *const u32) };
111    fidl_fuchsia_input::ConsumerControlButton::from_primitive_allow_unknown(discriminant)
112}
113
114#[cfg(test)]
115pub fn consumer_control_button_to_next(
116    button: &fidl_fuchsia_input::ConsumerControlButton,
117) -> fidl_next_fuchsia_input::ConsumerControlButton {
118    let discriminant = button.into_primitive();
119    fidl_next_fuchsia_input::ConsumerControlButton::from(discriminant)
120}
121
122/// Cursor messages.
123#[derive(Debug, PartialEq)]
124pub enum CursorMessage {
125    /// Set the position of the cursor.
126    SetPosition(Position),
127    /// Set the visibility of the cursor.
128    SetVisibility(bool),
129}
130
131/// Represents a generic 2D position.
132#[derive(Clone, Copy, Debug, PartialEq)]
133pub struct Position {
134    /// The x component of the position, in pixels.
135    pub x: f32,
136
137    /// The y component of the position, in pixels.
138    pub y: f32,
139}
140
141impl Position {
142    pub fn clamp(target: &mut Position, min: Position, max: Position) {
143        if (*target).x < min.x {
144            (*target).x = min.x;
145        }
146        if (*target).x > max.x {
147            (*target).x = max.x;
148        }
149
150        if (*target).y < min.y {
151            (*target).y = min.y;
152        }
153        if (*target).y > max.y {
154            (*target).y = max.y;
155        }
156    }
157
158    pub fn clamp_size(target: &mut Position, min: Size, max: Size) {
159        if (*target).x < min.width {
160            (*target).x = min.width;
161        }
162        if (*target).x > max.width {
163            (*target).x = max.width;
164        }
165
166        if (*target).y < min.height {
167            (*target).y = min.height;
168        }
169        if (*target).y > max.height {
170            (*target).y = max.height;
171        }
172    }
173
174    pub fn zero() -> Position {
175        Position { x: 0.0, y: 0.0 }
176    }
177}
178
179impl Add for Position {
180    type Output = Self;
181
182    #[inline]
183    fn add(self, other: Self) -> Self {
184        Self { x: self.x + other.x, y: self.y + other.y }
185    }
186}
187
188impl AddAssign for Position {
189    #[inline]
190    fn add_assign(&mut self, other: Self) {
191        *self = Self { x: self.x + other.x, y: self.y + other.y };
192    }
193}
194
195impl Sub for Position {
196    type Output = Self;
197
198    #[inline]
199    fn sub(self, other: Self) -> Self {
200        Self { x: self.x - other.x, y: self.y - other.y }
201    }
202}
203
204impl SubAssign for Position {
205    #[inline]
206    fn sub_assign(&mut self, other: Self) {
207        *self = Self { x: self.x - other.x, y: self.y - other.y };
208    }
209}
210
211impl Div for Position {
212    type Output = Self;
213
214    #[inline]
215    fn div(self, other: Self) -> Self {
216        Self { x: self.x / other.x, y: self.y / other.y }
217    }
218}
219
220impl DivAssign for Position {
221    #[inline]
222    fn div_assign(&mut self, other: Self) {
223        *self = Self { x: self.x / other.x, y: self.y / other.y };
224    }
225}
226
227impl Mul for Position {
228    type Output = Self;
229
230    #[inline]
231    fn mul(self, other: Self) -> Self {
232        Self { x: self.x * other.x, y: self.y * other.y }
233    }
234}
235
236impl MulAssign for Position {
237    #[inline]
238    fn mul_assign(&mut self, other: Self) {
239        *self = Self { x: self.x * other.x, y: self.y * other.y };
240    }
241}
242
243impl Mul<Size> for Position {
244    type Output = Self;
245
246    #[inline]
247    fn mul(self, other: Size) -> Position {
248        Self { x: self.x * other.width, y: self.y * other.height }
249    }
250}
251
252macro_rules! scale_position_impl {
253    ($($t:ty)*) => ($(
254        impl Div<$t> for Position {
255            type Output = Position;
256
257            #[inline]
258            fn div(self, other: $t) -> Position {
259                Self { x: self.x / other as f32, y: self.y / other as f32 }
260            }
261        }
262
263        impl DivAssign<$t> for Position {
264            #[inline]
265            fn div_assign(&mut self, other: $t) {
266                *self = Self { x: self.x / other as f32, y: self.y / other as f32 };
267            }
268        }
269
270        impl Mul<$t> for Position {
271            type Output = Position;
272
273            #[inline]
274            fn mul(self, other: $t) -> Position {
275                Self { x: self.x * other as f32, y: self.y * other as f32 }
276            }
277        }
278
279        impl Mul<Position> for $t {
280            type Output = Position;
281
282            #[inline]
283            fn mul(self, other: Position) -> Position {
284                Position { x: self as f32 * other.x, y: self as f32 * other.y }
285            }
286        }
287
288        impl MulAssign<$t> for Position {
289            #[inline]
290            fn mul_assign(&mut self, other: $t) {
291                *self = Self { x: self.x * other as f32, y: self.y * other as f32 };
292            }
293        }
294    )*)
295}
296
297scale_position_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }
298
299/// Represents a generic size.
300#[derive(Clone, Copy, Debug, PartialEq)]
301pub struct Size {
302    /// The width in pixels.
303    pub width: f32,
304
305    /// The height in pixels.
306    pub height: f32,
307}
308
309impl Size {
310    pub fn zero() -> Size {
311        Size { width: 0.0, height: 0.0 }
312    }
313}
314
315impl Add for Size {
316    type Output = Self;
317
318    #[inline]
319    fn add(self, other: Self) -> Self {
320        Self { width: self.width + other.width, height: self.height + other.height }
321    }
322}
323
324impl AddAssign for Size {
325    #[inline]
326    fn add_assign(&mut self, other: Self) {
327        *self = Self { width: self.width + other.width, height: self.height + other.height };
328    }
329}
330
331impl Sub for Size {
332    type Output = Self;
333
334    #[inline]
335    fn sub(self, other: Self) -> Self {
336        Self { width: self.width - other.width, height: self.height - other.height }
337    }
338}
339
340impl SubAssign for Size {
341    fn sub_assign(&mut self, other: Self) {
342        *self = Self { width: self.width - other.width, height: self.height - other.height };
343    }
344}
345
346impl Div for Size {
347    type Output = Self;
348
349    #[inline]
350    fn div(self, other: Self) -> Self {
351        Self { width: self.width / other.width, height: self.height / other.height }
352    }
353}
354
355impl DivAssign for Size {
356    #[inline]
357    fn div_assign(&mut self, other: Self) {
358        *self = Self { width: self.width / other.width, height: self.height / other.height };
359    }
360}
361
362impl Mul for Size {
363    type Output = Self;
364
365    #[inline]
366    fn mul(self, other: Self) -> Self {
367        Self { width: self.width * other.width, height: self.height * other.height }
368    }
369}
370
371impl MulAssign for Size {
372    #[inline]
373    fn mul_assign(&mut self, other: Self) {
374        *self = Self { width: self.width * other.width, height: self.height * other.height };
375    }
376}
377
378macro_rules! scale_size_impl {
379    ($($t:ty)*) => ($(
380        impl Div<$t> for Size {
381            type Output = Size;
382
383            #[inline]
384            fn div(self, other: $t) -> Size {
385                Self { width: self.width / other as f32, height: self.height / other as f32 }
386            }
387        }
388
389        impl DivAssign<$t> for Size {
390            #[inline]
391            fn div_assign(&mut self, other: $t) {
392                *self = Self { width: self.width / other as f32, height: self.height / other as f32 };
393            }
394        }
395
396        impl Mul<$t> for Size {
397            type Output = Size;
398
399            #[inline]
400            fn mul(self, other: $t) -> Size {
401                Self { width: self.width * other as f32, height: self.height * other as f32 }
402            }
403        }
404
405        impl MulAssign<$t> for Size {
406            #[inline]
407            fn mul_assign(&mut self, other: $t) {
408                *self = Self { width: self.width * other as f32, height: self.height * other as f32 };
409            }
410        }
411    )*)
412}
413
414scale_size_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 }