gui_server_api/msg/
capture.rs

1// SPDX-FileCopyrightText: 2025 Foundation Devices, Inc. <hello@foundation.xyz>
2// SPDX-License-Identifier: GPL-3.0-or-later
3
4//! Messages for device capture (screenshot), touch/key injection, and power-button injection.
5//! These work on both hardware and simulator — used by the passport-drive debug bridge.
6
7use num_traits::{FromPrimitive, ToPrimitive};
8use server::{AsScalar, FromScalar, SimpleMemoryMessage};
9use xous::MemoryRange;
10
11use crate::touch::{Touch, TouchKind};
12use crate::Key;
13
14/// Captures the current composited screen contents as raw pixel data.
15///
16/// On hardware the byte order is BGRA8888; on the simulator it is RGBA8888.
17/// Caller allocates a MemoryRange of SCREEN_WIDTH * SCREEN_HEIGHT * 4 bytes, lends it
18/// mutable to gui-server, which fills it with the composited pixel data.
19#[derive(Debug, server::Message)]
20#[response(())]
21pub struct CaptureScreen(pub MemoryRange);
22
23impl From<SimpleMemoryMessage> for CaptureScreen {
24    fn from(value: SimpleMemoryMessage) -> Self { Self(value.buf) }
25}
26
27impl From<CaptureScreen> for SimpleMemoryMessage {
28    fn from(val: CaptureScreen) -> Self { SimpleMemoryMessage { buf: val.0, arg1: 0, arg2: 0 } }
29}
30
31/// Injects a touch event into the GUI event pipeline as if it came from hardware.
32/// Works on both hardware and simulator.
33#[derive(Debug, server::Message)]
34pub struct InjectTouch(pub Touch);
35
36/// Injects a key press or release event into the active app as if it came from the keyboard.
37/// Works on both hardware and simulator — used by the passport-drive debug bridge.
38#[derive(Debug, server::Message)]
39pub struct InjectKey {
40    pub is_pressed: bool,
41    pub key: Key,
42}
43
44/// Injects a power button press or release into gui-server's power-button state machine.
45#[derive(Debug, server::Message)]
46pub struct InjectPowerButton(pub bool);
47
48impl AsScalar<3> for InjectKey {
49    fn as_scalar(&self) -> [u32; 3] {
50        let [kind, val] = self.key.as_scalar();
51        [u32::from(self.is_pressed), kind, val]
52    }
53}
54
55impl FromScalar<3> for InjectKey {
56    fn from_scalar([is_pressed, kind, val]: [u32; 3]) -> Self {
57        Self { is_pressed: is_pressed != 0, key: Key::from_scalar([kind, val]) }
58    }
59}
60
61// AsScalar / FromScalar impls for Touch — defined here (not in simulator.rs)
62// so they are available on hardware builds too.
63impl FromScalar<4> for Touch {
64    fn from_scalar([kind, id, x, y]: [u32; 4]) -> Self {
65        Touch {
66            kind: TouchKind::from_u32(kind).unwrap_or(TouchKind::Press),
67            id: id as usize,
68            x: x as usize,
69            y: y as usize,
70        }
71    }
72}
73
74impl AsScalar<4> for Touch {
75    fn as_scalar(&self) -> [u32; 4] {
76        [self.kind.to_u32().unwrap(), self.id as u32, self.x as u32, self.y as u32]
77    }
78}