Skip to main content

usehid_core/
hid.rs

1//! HID Report Descriptors
2//!
3//! Standard HID report descriptors for mouse, keyboard, and gamepad.
4
5/// Mouse report descriptor (5 buttons + X/Y relative movement + wheel)
6pub const MOUSE_REPORT_DESCRIPTOR: &[u8] = &[
7    0x05, 0x01,       // USAGE_PAGE (Generic Desktop)
8    0x09, 0x02,       // USAGE (Mouse)
9    0xa1, 0x01,       // COLLECTION (Application)
10    0x09, 0x01,       //   USAGE (Pointer)
11    0xa1, 0x00,       //   COLLECTION (Physical)
12    // Buttons
13    0x05, 0x09,       //     USAGE_PAGE (Button)
14    0x19, 0x01,       //     USAGE_MINIMUM (Button 1)
15    0x29, 0x05,       //     USAGE_MAXIMUM (Button 5)
16    0x15, 0x00,       //     LOGICAL_MINIMUM (0)
17    0x25, 0x01,       //     LOGICAL_MAXIMUM (1)
18    0x95, 0x05,       //     REPORT_COUNT (5)
19    0x75, 0x01,       //     REPORT_SIZE (1)
20    0x81, 0x02,       //     INPUT (Data,Var,Abs)
21    0x95, 0x01,       //     REPORT_COUNT (1)
22    0x75, 0x03,       //     REPORT_SIZE (3) - padding
23    0x81, 0x03,       //     INPUT (Cnst,Var,Abs)
24    // X, Y movement
25    0x05, 0x01,       //     USAGE_PAGE (Generic Desktop)
26    0x09, 0x30,       //     USAGE (X)
27    0x09, 0x31,       //     USAGE (Y)
28    0x15, 0x81,       //     LOGICAL_MINIMUM (-127)
29    0x25, 0x7f,       //     LOGICAL_MAXIMUM (127)
30    0x75, 0x08,       //     REPORT_SIZE (8)
31    0x95, 0x02,       //     REPORT_COUNT (2)
32    0x81, 0x06,       //     INPUT (Data,Var,Rel)
33    // Wheel
34    0x09, 0x38,       //     USAGE (Wheel)
35    0x15, 0x81,       //     LOGICAL_MINIMUM (-127)
36    0x25, 0x7f,       //     LOGICAL_MAXIMUM (127)
37    0x75, 0x08,       //     REPORT_SIZE (8)
38    0x95, 0x01,       //     REPORT_COUNT (1)
39    0x81, 0x06,       //     INPUT (Data,Var,Rel)
40    0xc0,             //   END_COLLECTION
41    0xc0,             // END_COLLECTION
42];
43
44/// Mouse report structure
45#[repr(C, packed)]
46#[derive(Debug, Clone, Copy, Default)]
47pub struct MouseReport {
48    pub buttons: u8,
49    pub x: i8,
50    pub y: i8,
51    pub wheel: i8,
52}
53
54/// Keyboard report descriptor (6-key rollover + modifiers)
55pub const KEYBOARD_REPORT_DESCRIPTOR: &[u8] = &[
56    0x05, 0x01,       // USAGE_PAGE (Generic Desktop)
57    0x09, 0x06,       // USAGE (Keyboard)
58    0xa1, 0x01,       // COLLECTION (Application)
59    // Modifier keys
60    0x05, 0x07,       //   USAGE_PAGE (Keyboard)
61    0x19, 0xe0,       //   USAGE_MINIMUM (Keyboard LeftControl)
62    0x29, 0xe7,       //   USAGE_MAXIMUM (Keyboard Right GUI)
63    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
64    0x25, 0x01,       //   LOGICAL_MAXIMUM (1)
65    0x75, 0x01,       //   REPORT_SIZE (1)
66    0x95, 0x08,       //   REPORT_COUNT (8)
67    0x81, 0x02,       //   INPUT (Data,Var,Abs)
68    // Reserved byte
69    0x95, 0x01,       //   REPORT_COUNT (1)
70    0x75, 0x08,       //   REPORT_SIZE (8)
71    0x81, 0x03,       //   INPUT (Cnst,Var,Abs)
72    // LEDs (output)
73    0x95, 0x05,       //   REPORT_COUNT (5)
74    0x75, 0x01,       //   REPORT_SIZE (1)
75    0x05, 0x08,       //   USAGE_PAGE (LEDs)
76    0x19, 0x01,       //   USAGE_MINIMUM (Num Lock)
77    0x29, 0x05,       //   USAGE_MAXIMUM (Kana)
78    0x91, 0x02,       //   OUTPUT (Data,Var,Abs)
79    0x95, 0x01,       //   REPORT_COUNT (1)
80    0x75, 0x03,       //   REPORT_SIZE (3)
81    0x91, 0x03,       //   OUTPUT (Cnst,Var,Abs)
82    // Key array (6 keys)
83    0x95, 0x06,       //   REPORT_COUNT (6)
84    0x75, 0x08,       //   REPORT_SIZE (8)
85    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
86    0x25, 0x65,       //   LOGICAL_MAXIMUM (101)
87    0x05, 0x07,       //   USAGE_PAGE (Keyboard)
88    0x19, 0x00,       //   USAGE_MINIMUM (Reserved)
89    0x29, 0x65,       //   USAGE_MAXIMUM (Keyboard Application)
90    0x81, 0x00,       //   INPUT (Data,Ary,Abs)
91    0xc0,             // END_COLLECTION
92];
93
94/// Keyboard report structure
95#[repr(C, packed)]
96#[derive(Debug, Clone, Copy, Default)]
97pub struct KeyboardReport {
98    pub modifiers: u8,
99    pub reserved: u8,
100    pub keys: [u8; 6],
101}
102
103/// Gamepad report descriptor
104pub const GAMEPAD_REPORT_DESCRIPTOR: &[u8] = &[
105    0x05, 0x01,       // USAGE_PAGE (Generic Desktop)
106    0x09, 0x05,       // USAGE (Game Pad)
107    0xa1, 0x01,       // COLLECTION (Application)
108    // Buttons (16)
109    0x05, 0x09,       //   USAGE_PAGE (Button)
110    0x19, 0x01,       //   USAGE_MINIMUM (Button 1)
111    0x29, 0x10,       //   USAGE_MAXIMUM (Button 16)
112    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
113    0x25, 0x01,   //   LOGICAL_MAXIMUM (1)
114    0x75, 0x01,       //   REPORT_SIZE (1)
115    0x95, 0x10,       //   REPORT_COUNT (16)
116    0x81, 0x02,       //   INPUT (Data,Var,Abs)
117    // Left stick
118    0x05, 0x01,       //   USAGE_PAGE (Generic Desktop)
119    0x09, 0x30,       //   USAGE (X)
120    0x09, 0x31,       //   USAGE (Y)
121    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
122    0x26, 0xff, 0x00, //   LOGICAL_MAXIMUM (255)
123    0x75, 0x08,       //   REPORT_SIZE (8)
124    0x95, 0x02,       //   REPORT_COUNT (2)
125    0x81, 0x02,       //   INPUT (Data,Var,Abs)
126    // Right stick
127    0x09, 0x32,       //   USAGE (Z)
128    0x09, 0x35,       //   USAGE (Rz)
129    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
130    0x26, 0xff, 0x00, //   LOGICAL_MAXIMUM (255)
131    0x75, 0x08,       //   REPORT_SIZE (8)
132    0x95, 0x02,       //   REPORT_COUNT (2)
133    0x81, 0x02,       //   INPUT (Data,Var,Abs)
134    // Triggers
135    0x09, 0x33,       //   USAGE (Rx)
136    0x09, 0x34,       //   USAGE (Ry)
137    0x15, 0x00,       //   LOGICAL_MINIMUM (0)
138    0x26, 0xff, 0x00, //   LOGICAL_MAXIMUM (255)
139    0x75, 0x08,       //   REPORT_SIZE (8)
140    0x95, 0x02,       //   REPORT_COUNT (2)
141    0x81, 0x02,       //   INPUT (Data,Var,Abs)
142    0xc0,             // END_COLLECTION
143];
144
145/// Gamepad report structure
146#[repr(C, packed)]
147#[derive(Debug, Clone, Copy, Default)]
148pub struct GamepadReport {
149    pub buttons: u16,
150    pub left_x: u8,
151    pub left_y: u8,
152    pub right_x: u8,
153    pub right_y: u8,
154    pub left_trigger: u8,
155    pub right_trigger: u8,
156}
157
158impl MouseReport {
159    pub fn as_bytes(&self) -> &[u8] {
160        unsafe {
161            std::slice::from_raw_parts(
162                self as *const Self as *const u8,
163                std::mem::size_of::<Self>(),
164            )
165        }
166    }
167}
168
169impl KeyboardReport {
170    pub fn as_bytes(&self) -> &[u8] {
171        unsafe {
172            std::slice::from_raw_parts(
173                self as *const Self as *const u8,
174                std::mem::size_of::<Self>(),
175            )
176        }
177    }
178}
179
180impl GamepadReport {
181    pub fn as_bytes(&self) -> &[u8] {
182        unsafe {
183            std::slice::from_raw_parts(
184                self as *const Self as *const u8,
185                std::mem::size_of::<Self>(),
186            )
187        }
188    }
189}