/src/serenity/Userland/Libraries/LibHID/ReportDescriptorDefinitions.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2025, Sönke Holz <sholz8530@gmail.com> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/DistinctNumeric.h> |
10 | | #include <AK/StdLibExtraDetails.h> |
11 | | #include <AK/Types.h> |
12 | | |
13 | | namespace HID { |
14 | | |
15 | | // https://www.usb.org/document-library/device-class-definition-hid-111 |
16 | | |
17 | | // 6.2.2 Report Descriptor |
18 | | |
19 | | enum class ItemType : u8 { |
20 | | Main = 0, |
21 | | Global = 1, |
22 | | Local = 2, |
23 | | Reserved = 3, |
24 | | }; |
25 | | |
26 | | // 5.3 Generic Item Format, 6.2.2.2 Short Items, 6.2.2.3 Long Items |
27 | | |
28 | | static constexpr u8 TAG_LONG_ITEM = 0b1111; |
29 | | |
30 | | struct [[gnu::packed]] ItemHeader { |
31 | | u8 size : 2; |
32 | | ItemType type : 2; |
33 | | u8 tag : 4; |
34 | | |
35 | 13.2M | u8 real_size() const { return size == 3 ? 4 : size; } |
36 | | }; |
37 | | static_assert(AssertSize<ItemHeader, 1>()); |
38 | | |
39 | | // 6.2.2.4 Main Items |
40 | | |
41 | | enum class MainItemTag : u8 { |
42 | | Input = 0b1000, |
43 | | Output = 0b1001, |
44 | | Feature = 0b1011, |
45 | | Collection = 0b1010, |
46 | | EndCollection = 0b1100, |
47 | | }; |
48 | | |
49 | | // 6.2.2.5 Input, Output, and Feature Items |
50 | | |
51 | | struct [[gnu::packed]] InputItemData { |
52 | | u8 constant : 1; |
53 | | u8 variable : 1; |
54 | | u8 relative : 1; |
55 | | u8 wrap : 1; |
56 | | u8 nonlinear : 1; |
57 | | u8 no_preferred_state : 1; |
58 | | u8 has_null_state : 1; |
59 | | u8 : 1; |
60 | | u8 buffered_bytes : 1; |
61 | | }; |
62 | | static_assert(AssertSize<InputItemData, 2>()); |
63 | | |
64 | | struct [[gnu::packed]] OutputItemData { |
65 | | u8 constant : 1; |
66 | | u8 variable : 1; |
67 | | u8 relative : 1; |
68 | | u8 wrap : 1; |
69 | | u8 nonlinear : 1; |
70 | | u8 no_preferred_state : 1; |
71 | | u8 has_null_state : 1; |
72 | | u8 volatile_ : 1; |
73 | | u8 buffered_bytes : 1; |
74 | | }; |
75 | | static_assert(AssertSize<OutputItemData, 2>()); |
76 | | |
77 | | struct [[gnu::packed]] FeatureItemData { |
78 | | u8 constant : 1; |
79 | | u8 variable : 1; |
80 | | u8 relative : 1; |
81 | | u8 wrap : 1; |
82 | | u8 nonlinear : 1; |
83 | | u8 no_preferred_state : 1; |
84 | | u8 has_null_state : 1; |
85 | | u8 volatile_ : 1; |
86 | | u8 buffered_bytes : 1; |
87 | | }; |
88 | | static_assert(AssertSize<FeatureItemData, 2>()); |
89 | | |
90 | | // 6.2.2.6 Collection, End Collection Items |
91 | | |
92 | | enum class CollectionType : u8 { |
93 | | Physical = 0x00, |
94 | | Application = 0x01, |
95 | | Logical = 0x02, |
96 | | Report = 0x03, |
97 | | NamedArray = 0x04, |
98 | | UsageSwitch = 0x05, |
99 | | UsageModifier = 0x06, |
100 | | }; |
101 | | |
102 | | // 6.2.2.7 Global Items |
103 | | |
104 | | enum class GlobalItemTag : u8 { |
105 | | UsagePage = 0b0000, |
106 | | LogicalMinimum = 0b0001, |
107 | | LogicalMaximum = 0b0010, |
108 | | PhysicalMinimum = 0b0011, |
109 | | PhysicalMaximum = 0b0100, |
110 | | UnitExponent = 0b0101, |
111 | | Unit = 0b0110, |
112 | | ReportSize = 0b0111, |
113 | | ReportID = 0b1000, |
114 | | ReportCount = 0b1001, |
115 | | Push = 0b1010, |
116 | | Pop = 0b1011, |
117 | | }; |
118 | | |
119 | | // 6.2.2.8 Local Items |
120 | | |
121 | | enum class LocalItemTag : u8 { |
122 | | Usage = 0b0000, |
123 | | UsageMinimum = 0b0001, |
124 | | UsageMaximum = 0b0010, |
125 | | DesignatorIndex = 0b0011, |
126 | | DesignatorMinimum = 0b0100, |
127 | | DesignatorMaximum = 0b0101, |
128 | | StringIndex = 0b0111, |
129 | | StringMinimum = 0b1000, |
130 | | StringMaximum = 0b1001, |
131 | | Delimiter = 0b1010, |
132 | | }; |
133 | | |
134 | | } |
135 | | |
136 | | template<> |
137 | | class AK::Traits<HID::ItemHeader> : public DefaultTraits<HID::ItemHeader> { |
138 | | public: |
139 | 0 | static constexpr bool is_trivially_serializable() { return true; } |
140 | | }; |