hid_report/
global_items.rs

1use crate::{__data_to_signed, __data_to_unsigned, macros::*};
2use alloc::vec::Vec;
3use std::fmt::Display;
4
5__impls_for_short_items! {
6    /// Unsigned integer specifying the current Usage Page.
7    ///
8    /// Since a usage are 32 bit values, Usage
9    /// Page items can be used to conserve space in a
10    /// report descriptor by setting the high order 16 bits
11    /// of a subsequent usages. Any usage that follows
12    /// which is defines 16 bits or less is interpreted as a
13    /// Usage ID and concatenated with the Usage Page
14    /// to form a 32 bit Usage.
15    ///
16    /// # Data (Little Endian)
17    ///
18    /// * 0x00: Undefined
19    /// * 0x01: Generic Desktop
20    /// * 0x02: Simulation Controls
21    /// * 0x03: VR Controls
22    /// * 0x04: Sport Controls
23    /// * 0x05: Game Controls
24    /// * 0x06: Generic Device Controls
25    /// * 0x07: Keyboard/Keypad
26    /// * 0x08: LED
27    /// * 0x09: Button
28    /// * 0x0A: Ordinal
29    /// * 0x0B: Telephony Device
30    /// * 0x0C: Consumer
31    /// * 0x0D: Digitizer
32    /// * 0x0E: Haptics
33    /// * 0x0F: PID
34    /// * 0x10: Unicode
35    /// * 0x12: Eye and Head Trackers
36    /// * 0x14: Auxiliary Display
37    /// * 0x20: Sensors
38    /// * 0x40: Medical Instrument
39    /// * 0x41: Braille Display
40    /// * 0x59: Lighting And Illumination
41    /// * 0x80-0x83: Monitor
42    /// * 0x84-0x87: Power
43    /// * 0x8C: Bar Code Scanner
44    /// * 0x8D: Scale
45    /// * 0x8E: Magnetic Stripe Reading
46    /// * 0x8F: Reserved Point of Sale
47    /// * 0x90: Camera Control
48    /// * 0x91: Arcade
49    /// * 0x92: Gaming Device
50    /// * 0xF1D0: FIDO Alliance
51    /// * 0xFF00-x0FFFF: Vendor Defined
52    /// * Other: Reserved
53    UsagePage: 0b0000_0100;
54    /// Extent value in logical units. This is the
55    /// minimum value that a variable or array item will
56    /// report.
57    ///
58    /// For example, a mouse reporting x
59    /// position values from 0 to 128 would have a
60    /// Logical Minimum of 0 and a [Logical Maximum](LogicalMaximum)
61    /// of 128.
62    LogicalMinimum: 0b0001_0100;
63    /// Extent value in logical units. This is the
64    /// maximum value that a variable or array item will
65    /// report.
66    ///
67    /// For example, a mouse reporting x
68    /// position values from 0 to 128 would have a
69    /// [Logical Minimum](LogicalMinimum) of 0 and a Logical Maximum
70    /// of 128.
71    LogicalMaximum: 0b0010_0100;
72    /// Minimum value for the physical extent of a variable item.
73    /// This represents the [Logical Minimum](LogicalMinimum)
74    /// with units applied to it.
75    PhysicalMinimum: 0b0011_0100;
76    /// Maximum value for the physical extent of a variable item.
77    /// This represents the [Logical Maximum](LogicalMaximum)
78    /// with units applied to it.
79    PhysicalMaximum: 0b0100_0100;
80    /// Value of the unit exponent in base 10.
81    ///
82    /// # Data (Little Endian)
83    ///
84    /// * 0x0: 0
85    /// * 0x1: 1
86    /// * 0x2: 2
87    /// * 0x3: 3
88    /// * 0x4: 4
89    /// * 0x5: 5
90    /// * 0x6: 6
91    /// * 0x7: 7
92    /// * 0x8: -8
93    /// * 0x9: -7
94    /// * 0xA: -6
95    /// * 0xB: -5
96    /// * 0xC: -4
97    /// * 0xD: -3
98    /// * 0xE: -2
99    /// * 0xF: -1
100    UnitExponent: 0b0101_0100;
101    /// Unit values.
102    ///
103    /// # Data (Little Endian)
104    ///
105    /// The Unit item qualifies value in the unit of [nibbles](https://en.wikipedia.org/wiki/Nibble).
106    /// i.e., bit 3-0 is the nibble 0, bit 7-4 is the nibble 1, and so on.
107    ///
108    /// | Nibble | System | 0 | 1 | 2 | 3 | 4 |
109    /// | --- | --- | --- | --- | --- | --- | --- |
110    /// | 0 | System | None | SI Linear | SI Rotation | English Linear | English Rotation |
111    /// | 1 | Length | None | Centimeter | Radians | Inch | Degrees |
112    /// | 2 | Mass | None | Gram | Gram | Slug | Slug |
113    /// | 3 | Time | None | Seconds | Seconds | Seconds | Seconds |
114    /// | 4 | Temperature | None | Kelvin | Kelvin | Fahrenheit | Fahrenheit |
115    /// | 5 | Current | None | Ampere | Ampere | Ampere | Ampere |
116    /// | 6 | Luminous Intensity | None | Candela | Candela | Candela | Candela |
117    ///
118    /// Codes 0x5-0xE are reserved; code 0xF is vendor-defined.
119    Unit: 0b0110_0100;
120    /// Unsigned integer specifying the size of the report
121    /// fields in bits.
122    ///
123    /// This allows the parser to build an
124    /// item map for the report handler to use.
125    ReportSize: 0b0111_0100;
126    /// Unsigned value that specifies the Report ID.
127    ///
128    /// If a Report ID tag is used anywhere in Report
129    /// descriptor, all data reports for the device are
130    /// preceded by a single byte ID field. All items
131    /// succeeding the first Report ID tag but preceding
132    /// a second Report ID tag are included in a report
133    /// prefixed by a 1-byte ID. All items succeeding the
134    /// second but preceding a third Report ID tag are
135    /// included in a second report prefixed by a second
136    /// ID, and so on.
137    ///
138    /// This Report ID value indicates the prefix added
139    /// to a particular report. For example, a Report
140    /// descriptor could define a 3-byte report with a
141    /// Report ID of `01`. This device would generate a
142    /// 4-byte data report in which the first byte is `01`.
143    /// The device may also generate other reports, each
144    /// with a unique ID. This allows the host to
145    /// distinguish different types of reports arriving
146    /// over a single interrupt in pipe. And allows the
147    /// device to distinguish different types of reports
148    /// arriving over a single interrupt out pipe. Report
149    /// ID zero is reserved and should not be used.
150    ReportId: 0b1000_0100;
151    /// Unsigned integer specifying the number of data
152    /// fields for the item; determines how many fields
153    /// are included in the report for this particular item
154    /// (and consequently how many bits are added to
155    /// the report).
156    ReportCount: 0b1001_0100;
157    /// Places a copy of the global item state table on the stack.
158    Push: 0b1010_0100;
159    /// Replaces the item state table with the top structure from the stack.
160    Pop: 0b1011_0100;
161}
162
163impl Display for UsagePage {
164    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165        match self.data().len() {
166            0 => write!(f, "Usage Page"),
167            1.. => write!(
168                f,
169                "Usage Page ({})",
170                match __data_to_unsigned(self.data()) {
171                    0x00 => "Undefined",
172                    0x01 => "Generic Desktop",
173                    0x02 => "Simulation Controls",
174                    0x03 => "VR Controls",
175                    0x04 => "Sport Controls",
176                    0x05 => "Game Controls",
177                    0x06 => "Generic Device Controls",
178                    0x07 => "Keyboard/Keypad",
179                    0x08 => "LED",
180                    0x09 => "Button",
181                    0x0A => "Ordinal",
182                    0x0B => "Telephony Device",
183                    0x0C => "Consumer",
184                    0x0D => "Digitizers",
185                    0x0E => "Haptics",
186                    0x0F => "Physical Input Device",
187                    0x10 => "Unicode",
188                    0x11 => "SoC",
189                    0x12 => "Eye and Head Trackers",
190                    0x14 => "Auxiliary Display",
191                    0x20 => "Sensors",
192                    0x40 => "Medical Instrument",
193                    0x41 => "Braille Display",
194                    0x59 => "Lighting And Illumination",
195                    0x80 => "Monitor",
196                    0x81 => "Monitor Enumerated",
197                    0x82 => "VESA Virtual Controls",
198                    0x84 => "Power",
199                    0x85 => "Battery System",
200                    0x8C => "Bar Code Scanner",
201                    0x8D => "Scale",
202                    0x8E => "Magnetic Stripe Reading",
203                    0x90 => "Camera Control",
204                    0x91 => "Arcade",
205                    0x92 => "Gaming Device",
206                    0xF1D0 => "FIDO Alliance",
207                    0xFF00..=0xFFFF => "Vendor Defined",
208                    _ => "Reserved",
209                }
210            ),
211        }
212    }
213}
214
215impl Display for LogicalMinimum {
216    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
217        match self.data().len() {
218            0 => write!(f, "Logical Minimum"),
219            1.. => write!(f, "Logical Minimum ({})", __data_to_signed(self.data())),
220        }
221    }
222}
223
224impl Display for LogicalMaximum {
225    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
226        match self.data().len() {
227            0 => write!(f, "Logical Maximum"),
228            1.. => write!(f, "Logical Maximum ({})", __data_to_signed(self.data())),
229        }
230    }
231}
232
233impl Display for PhysicalMinimum {
234    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
235        match self.data().len() {
236            0 => write!(f, "Physical Minimum"),
237            1.. => write!(f, "Physical Minimum ({})", __data_to_signed(self.data())),
238        }
239    }
240}
241
242impl Display for PhysicalMaximum {
243    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244        match self.data().len() {
245            0 => write!(f, "Physical Maximum"),
246            1.. => write!(f, "Physical Maximum ({})", __data_to_signed(self.data())),
247        }
248    }
249}
250
251impl Display for UnitExponent {
252    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253        match self.data().len() {
254            0 => write!(f, "Unit Exponent"),
255            1.. => match __data_to_signed(self.data()) {
256                exp @ 0..=7 => write!(f, "Unit Exponent {exp}"),
257                exp @ 8..=15 => write!(f, "Unit Exponent {}", exp - 16),
258                _ => write!(f, "Unit Exponent"),
259            },
260        }
261    }
262}
263
264impl Display for Unit {
265    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
266        let mut units = Vec::new();
267        if let [byte, ..] = self.data() {
268            let system = byte & 0x0F;
269            let length = (byte & 0xF0) >> 4;
270            match system {
271                1 => units.push("System: SI Linear"),
272                2 => units.push("System: SI Rotation"),
273                3 => units.push("System: English Linear"),
274                4 => units.push("System: English Rotation"),
275                5..=0xE => units.push("System: Reserved"),
276                0xF => units.push("System: Vendor Defined"),
277                _ => unreachable!(),
278            }
279            match length {
280                1 => units.push("Length: Centimeter"),
281                2 => units.push("Length: Radians"),
282                3 => units.push("Length: Inch"),
283                4 => units.push("Length: Degrees"),
284                5..=0xE => units.push("Length: Reserved"),
285                0xF => units.push("Length: Vendor Defined"),
286                _ => unreachable!(),
287            }
288        }
289        if let [_, byte, ..] = self.data() {
290            let mass = byte & 0x0F;
291            let time = (byte & 0xF0) >> 4;
292            match mass {
293                1 | 2 => units.push("Mass: Gram"),
294                3 | 4 => units.push("Mass: Slug"),
295                5..=0xE => units.push("Mass: Reserved"),
296                0xF => units.push("Mass: Vendor Defined"),
297                _ => unreachable!(),
298            }
299            match time {
300                1..=4 => units.push("Time: Seconds"),
301                5..=0xE => units.push("Time: Reserved"),
302                0xF => units.push("Time: Vendor Defined"),
303                _ => unreachable!(),
304            }
305        }
306        if let [_, _, byte, ..] = self.data() {
307            let temperature = byte & 0x0F;
308            let current = (byte & 0xF0) >> 4;
309            match temperature {
310                1 | 2 => units.push("Temperature: Kelvin"),
311                3 | 4 => units.push("Temperature: Fahrenheit"),
312                5..=0xE => units.push("Temperature: Reserved"),
313                0xF => units.push("Temperature: Vendor Defined"),
314                _ => unreachable!(),
315            }
316            match current {
317                1..=4 => units.push("Current: Ampere"),
318                5..=0xE => units.push("Current: Reserved"),
319                0xF => units.push("Current: Vendor Defined"),
320                _ => unreachable!(),
321            }
322        }
323        if let [_, _, _, byte, ..] = self.data() {
324            let luminous_intensity = byte & 0x0F;
325            match luminous_intensity {
326                1..=4 => units.push("Luminous Intensity: Candela"),
327                5..=0xE => units.push("Luminous Intensity: Reserved"),
328                0xF => units.push("Luminous Intensity: Vendor Defined"),
329                _ => unreachable!(),
330            }
331        }
332        if units.is_empty() {
333            write!(f, "Unit")
334        } else {
335            write!(f, "Unit({})", units.join(", "))
336        }
337    }
338}
339
340impl Display for ReportSize {
341    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
342        match self.data().len() {
343            0 => write!(f, "Report Size"),
344            1.. => write!(f, "Report Size ({})", __data_to_unsigned(self.data())),
345        }
346    }
347}
348
349impl Display for ReportId {
350    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
351        match self.data().len() {
352            0 => write!(f, "Report ID"),
353            1.. => write!(f, "Report ID ({})", __data_to_unsigned(self.data())),
354        }
355    }
356}
357
358impl Display for ReportCount {
359    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
360        match self.data().len() {
361            0 => write!(f, "Report Count"),
362            1.. => write!(f, "Report Count ({})", __data_to_unsigned(self.data())),
363        }
364    }
365}
366
367impl Display for Push {
368    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
369        write!(f, "Push")
370    }
371}
372
373impl Display for Pop {
374    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375        write!(f, "Pop")
376    }
377}