1#![expect(dead_code)]
5
6use guid::Guid;
7use static_assertions::const_assert_eq;
8use std::fmt;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13
14pub const INTERFACE_GUID: Guid = guid::guid!("cfa8b69e-5b4a-4cc0-b98b-8ba1a1f3f95a");
16
17pub const INSTANCE_GUID: Guid = guid::guid!("58f75a6d-d949-4320-99e1-a2a2576d581c");
19
20const fn make_version(major: u16, minor: u16) -> u32 {
22 (minor as u32) | ((major as u32) << 16)
23}
24
25pub const SYNTHHID_INPUT_VERSION: u32 = make_version(2, 0);
26
27pub const SYNTHHID_PROTOCOL_REQUEST: u32 = 0;
28pub const SYNTHHID_PROTOCOL_RESPONSE: u32 = 1;
29pub const SYNTHHID_INIT_DEVICE_INFO: u32 = 2;
30pub const SYNTHHID_INIT_DEVICE_INFO_ACK: u32 = 3;
31pub const SYNTHHID_PROTOCOL_INPUT_REPORT: u32 = 4;
32pub const SYNTHHID_HID_MAX: u32 = 5;
33
34pub const HID_VENDOR_ID: u16 = 0x045e;
35pub const HID_PRODUCT_ID: u16 = 0x0621;
36pub const HID_VERSION_ID: u16 = 0x0001;
37
38pub const SYNTHHID_INPUT_REPORT_SIZE: u8 = 16;
39pub const MAX_HID_MESSAGE_SIZE: u16 = 512;
40pub const MAX_HID_REPORT_DESCRIPTOR: u16 = 256;
41
42#[repr(C)]
44#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
45pub struct HidAttributes {
46 pub size: u32,
47 pub vendor_id: u16,
48 pub product_id: u16,
49 pub version_id: u16,
50 pub padding: [u16; 11],
51}
52
53const_assert_eq!(0x20, size_of::<HidAttributes>());
54
55#[repr(C, packed)]
56#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
57pub struct HidDescriptor {
58 pub length: u8,
59 pub descriptor_type: u8,
60 pub hid: u16,
61 pub country: u8,
62 pub num_descriptors: u8,
63 pub descriptor_list: HidDescriptorList,
64}
65
66const_assert_eq!(0x9, size_of::<HidDescriptor>());
67
68#[repr(C, packed)]
69#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
70pub struct HidDescriptorList {
71 pub report_type: u8,
72 pub report_length: u16,
73}
74
75const_assert_eq!(0x3, size_of::<HidDescriptorList>());
76
77#[repr(C)]
78#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
79pub struct MessageHeader {
80 pub message_type: u32,
81 pub message_size: u32,
82}
83
84const_assert_eq!(0x8, size_of::<MessageHeader>());
85
86#[repr(C)]
87#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
88pub struct MessageProtocolRequest {
89 pub version: u32,
90}
91
92const_assert_eq!(0x4, size_of::<MessageProtocolRequest>());
93
94#[repr(C, packed)]
95#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
96pub struct MessageProtocolResponse {
97 pub version_requested: u32,
98 pub accepted: u8,
99}
100
101const_assert_eq!(0x5, size_of::<MessageProtocolResponse>());
102
103#[repr(C, packed)]
104#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
105pub struct MessageDeviceInfo {
106 pub device_attributes: HidAttributes,
107 pub descriptor_info: HidDescriptor,
108 pub report_descriptor: [u8; 128],
109}
110
111const_assert_eq!(169, size_of::<MessageDeviceInfo>());
112
113impl fmt::Debug for MessageDeviceInfo {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 f.debug_struct("MessageDeviceInfo")
116 .field("descriptor_info", &self.descriptor_info)
117 .finish()
118 }
119}
120
121#[repr(C)]
122#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
123pub struct MessageDeviceInfoAck {
124 pub acknowledged: u8,
125}
126
127const_assert_eq!(1, size_of::<MessageDeviceInfoAck>());
128
129#[repr(C, packed)]
130#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
131pub struct MessageInputReport {
132 pub input_report: MousePacket,
133}
134
135const_assert_eq!(7, size_of::<MessageInputReport>());
136
137pub const REPORT_DESCRIPTOR: [u8; 67] = [
138 0x05, 0x01, 0x09, 0x02, 0xA1, 0x01, 0x09, 0x01, 0xA1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x05, 0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x03, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 0x15, 0x00, 0x26, 0xFF, 0x7F, 0x75, 0x10, 0x95, 0x02, 0x81, 0x02, 0x05, 0x01, 0x09, 0x38, 0x16, 0x01, 0x80, 0x26, 0xFF, 0x7F, 0x75, 0x10, 0x95, 0x01, 0x81, 0x06, 0xC0, 0xC0, ];
175
176pub const HID_MOUSE_BUTTON_LEFT: u8 = 0x01;
177pub const HID_MOUSE_BUTTON_RIGHT: u8 = 0x02;
178pub const HID_MOUSE_BUTTON_MIDDLE: u8 = 0x04;
179
180pub const MOUSE_NUMBER_BUTTONS: usize = 5;
181
182pub enum MouseButton {
183 Left = 0,
184 Right = 1,
185 Middle = 2,
186 Fourth = 3,
187 Fifth = 4,
188}
189
190#[derive(Copy, Clone, Debug)]
191pub enum ScrollType {
192 Down = -1,
194 NoChange = 0,
195 Up = 1,
196}
197
198pub const MOUSE_EVENT_FLAG_XY_ABSOLUTE: u32 = 1 << 0;
199
200pub const fn event_no_change(button: u8) -> u32 {
201 1 << ((button as u32) + 1)
202}
203
204pub const MOUSE_EVENT_FLAG_LEFT_BUTTON_NO_CHANGE: u32 = event_no_change(MouseButton::Left as u8);
205pub const MOUSE_EVENT_FLAG_RIGHT_BUTTON_NO_CHANGE: u32 = event_no_change(MouseButton::Right as u8);
206pub const MOUSE_EVENT_FLAG_MIDDLE_BUTTON_NO_CHANGE: u32 =
207 event_no_change(MouseButton::Middle as u8);
208pub const MOUSE_EVENT_FLAG_FOURTH_BUTTON_NO_CHANGE: u32 =
209 event_no_change(MouseButton::Fourth as u8);
210pub const MOUSE_EVENT_FLAG_FIFTH_BUTTON_NO_CHANGE: u32 = event_no_change(MouseButton::Fifth as u8);
211
212pub const MOUSE_EVENT_FLAG_ALL_BUTTONS_NO_CHANGE: u32 = MOUSE_EVENT_FLAG_LEFT_BUTTON_NO_CHANGE
213 | MOUSE_EVENT_FLAG_MIDDLE_BUTTON_NO_CHANGE
214 | MOUSE_EVENT_FLAG_RIGHT_BUTTON_NO_CHANGE
215 | MOUSE_EVENT_FLAG_FOURTH_BUTTON_NO_CHANGE
216 | MOUSE_EVENT_FLAG_FIFTH_BUTTON_NO_CHANGE;
217
218pub const fn event_single_change(button: MouseButton) -> u32 {
219 MOUSE_EVENT_FLAG_ALL_BUTTONS_NO_CHANGE & (!(event_no_change(button as u8)))
220}
221
222pub const MOUSE_EVENT_FLAG_FORCE_REPORT_EVENT: u32 = 1 << 8;
223
224#[repr(C, packed)]
225#[derive(Copy, Clone, Debug, IntoBytes, Immutable, KnownLayout, FromBytes)]
226pub struct MousePacket {
227 pub button_data: u8,
228
229 pub x: u16,
230 pub y: u16,
231 pub z: i16,
232}
233
234const_assert_eq!(7, size_of::<MousePacket>());