├── .editorconfig ├── .gitattributes ├── .github └── workflows │ ├── publish.yml │ ├── publishusages.yml │ └── validate.yml ├── .gitignore ├── .gitmodules ├── DevDecoder Icon.png ├── HIDDevices.Generator ├── AnalyzerReleases.Shipped.md ├── AnalyzerReleases.Unshipped.md ├── Diagnostics.cs ├── HIDDevices.Generator.csproj ├── HidUsageGenerator.cs ├── HidUsageId.cs ├── HidUsageKind.cs ├── HidUsagePage.cs ├── HidUsagePageKind.cs ├── HidUsageTables.cs ├── IndentStringBuilder.cs └── UsagePageGenerator.cs ├── HIDDevices.Sample ├── HIDDevices.Sample.csproj ├── ISample.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Resources.Designer.cs ├── Resources.resx ├── Sample.cs ├── Samples │ ├── DependencyInjectionSample.cs │ └── GameLoopSample.cs └── SimpleConsoleLogger.cs ├── HIDDevices.Test ├── HIDDevices.Test.csproj └── Tests.cs ├── HIDDevices.Usages ├── Generated │ ├── HIDDevices.Generator │ │ └── HIDDevices.Generator.UsagePageGenerator │ │ │ ├── ArcadePage.g.cs │ │ │ ├── ArcadeUsagePage.g.cs │ │ │ ├── AuxiliaryDisplayPage.g.cs │ │ │ ├── AuxiliaryDisplayUsagePage.g.cs │ │ │ ├── BarcodeScannerPage.g.cs │ │ │ ├── BarcodeScannerUsagePage.g.cs │ │ │ ├── BatterySystemPage.g.cs │ │ │ ├── BatterySystemUsagePage.g.cs │ │ │ ├── BrailleDisplayPage.g.cs │ │ │ ├── BrailleDisplayUsagePage.g.cs │ │ │ ├── ButtonPage.g.cs │ │ │ ├── ButtonUsagePage.g.cs │ │ │ ├── CameraControlPage.g.cs │ │ │ ├── CameraControlUsagePage.g.cs │ │ │ ├── ConsumerPage.g.cs │ │ │ ├── ConsumerUsagePage.g.cs │ │ │ ├── DigitizersPage.g.cs │ │ │ ├── DigitizersUsagePage.g.cs │ │ │ ├── EyeAndHeadTrackersPage.g.cs │ │ │ ├── EyeAndHeadTrackersUsagePage.g.cs │ │ │ ├── FIDOAlliancePage.g.cs │ │ │ ├── FIDOAllianceUsagePage.g.cs │ │ │ ├── GameControlsPage.g.cs │ │ │ ├── GameControlsUsagePage.g.cs │ │ │ ├── GenericDesktopPage.g.cs │ │ │ ├── GenericDesktopUsagePage.g.cs │ │ │ ├── GenericDeviceControlsPage.g.cs │ │ │ ├── GenericDeviceControlsUsagePage.g.cs │ │ │ ├── HapticsPage.g.cs │ │ │ ├── HapticsUsagePage.g.cs │ │ │ ├── KeyboardKeypadPage.g.cs │ │ │ ├── KeyboardKeypadUsagePage.g.cs │ │ │ ├── LEDPage.g.cs │ │ │ ├── LEDUsagePage.g.cs │ │ │ ├── LightingAndIlluminationPage.g.cs │ │ │ ├── LightingAndIlluminationUsagePage.g.cs │ │ │ ├── MagneticStripeReaderPage.g.cs │ │ │ ├── MagneticStripeReaderUsagePage.g.cs │ │ │ ├── MedicalInstrumentPage.g.cs │ │ │ ├── MedicalInstrumentUsagePage.g.cs │ │ │ ├── MonitorEnumeratedPage.g.cs │ │ │ ├── MonitorEnumeratedUsagePage.g.cs │ │ │ ├── MonitorPage.g.cs │ │ │ ├── MonitorUsagePage.g.cs │ │ │ ├── OrdinalPage.g.cs │ │ │ ├── OrdinalUsagePage.g.cs │ │ │ ├── PhysicalInputDevicePage.g.cs │ │ │ ├── PhysicalInputDeviceUsagePage.g.cs │ │ │ ├── PowerPage.g.cs │ │ │ ├── PowerUsagePage.g.cs │ │ │ ├── ScalesPage.g.cs │ │ │ ├── ScalesUsagePage.g.cs │ │ │ ├── SensorsPage.g.cs │ │ │ ├── SensorsUsagePage.g.cs │ │ │ ├── SimulationControlsPage.g.cs │ │ │ ├── SimulationControlsUsagePage.g.cs │ │ │ ├── SoCPage.g.cs │ │ │ ├── SoCUsagePage.g.cs │ │ │ ├── SportControlsPage.g.cs │ │ │ ├── SportControlsUsagePage.g.cs │ │ │ ├── TelephonyDevicePage.g.cs │ │ │ ├── TelephonyDeviceUsagePage.g.cs │ │ │ ├── UsagePage.g.cs │ │ │ ├── VESAVirtualControlsPage.g.cs │ │ │ ├── VESAVirtualControlsUsagePage.g.cs │ │ │ ├── VRControlsPage.g.cs │ │ │ └── VRControlsUsagePage.g.cs │ ├── HidUsageTables.json │ └── hut1_5.pdf ├── HIDDevices.Usages.csproj ├── Usage.cs ├── UsagePage.cs ├── UsageType.cs ├── UsageTypeGroup.cs ├── UsageTypes.cs └── readme.md ├── HIDDevices.sln ├── HIDDevices ├── Attributes │ ├── ControlAttribute.cs │ └── DeviceAttribute.cs ├── Control.cs ├── ControlChange.cs ├── Controllers │ ├── ControlInfo.cs │ ├── ControlValue.cs │ ├── Controller.cs │ ├── ControllerInfo.cs │ ├── CreateControllerDelegate.cs │ └── Gamepad.cs ├── Converters │ ├── BooleanConverter.cs │ ├── ControlConverter.cs │ ├── Direction.cs │ ├── DirectionConverter.cs │ ├── LeftTriggerConverter.cs │ ├── RangeConverter.cs │ ├── RightTriggerConverter.cs │ └── SignedConverter.cs ├── Device.cs ├── DeviceExtensions.cs ├── Devices.cs ├── Events.cs ├── HIDDevices.csproj ├── HIDDevices.csproj.DotSettings ├── LoggingExtensions.cs ├── Resources.Designer.cs └── Resources.resx ├── HIDUsageTablesPDF.url ├── LICENSE.txt ├── NOTICE.txt ├── readme.md └── version.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish HIDDevices 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | paths-ignore: 8 | - '**/.md' 9 | - '**/.txt' 10 | - '.github/publishusages.yml' 11 | - '.github/validate.yml' 12 | - 'HIDDevices.Generator/**' 13 | - 'HIDDevices.Usages/**' 14 | - 'HIDDevices.Sample/**' 15 | - 'HIDDevices.Test/**' 16 | 17 | jobs: 18 | publish: 19 | 20 | runs-on: windows-latest 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | with: 25 | fetch-depth: 0 # Avoid shallow clone so NBGV can do its work. 26 | submodules: 'recursive' 27 | - name: Set version 28 | uses: dotnet/nbgv@v0.4.2 29 | with: 30 | setAllVars: true 31 | - name: Setup .NET 32 | uses: actions/setup-dotnet@v4 33 | with: 34 | dotnet-version: '9.0.x' 35 | - name: Install dependencies 36 | run: dotnet restore 37 | - name: Build 38 | run: dotnet build --configuration Release --no-restore -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 39 | - name: Test 40 | run: dotnet test --configuration Release --no-build --verbosity normal -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 41 | - name: Publish 42 | uses: alirezanet/publish-nuget@v3.1.0 43 | with: 44 | PROJECT_FILE_PATH: HIDDevices/HIDDevices.csproj 45 | NUGET_KEY: ${{secrets.NUGET_API_KEY}} 46 | INCLUDE_SYMBOLS: true 47 | VERSION_STATIC: ${{env.NBGV_Version}} 48 | -------------------------------------------------------------------------------- /.github/workflows/publishusages.yml: -------------------------------------------------------------------------------- 1 | name: Build and Publish HIDDevices.Usages 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | paths-ignore: 8 | - '**/.md' 9 | - '**/.txt' 10 | - '.github/publish.yml' 11 | - '.github/validate.yml' 12 | - 'HIDDevices/**' 13 | - 'HIDDevices.Sample/**' 14 | - 'HIDDevices.Test/**' 15 | 16 | jobs: 17 | publish: 18 | 19 | runs-on: windows-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 # Avoid shallow clone so NBGV can do its work. 25 | submodules: 'recursive' 26 | - name: Set version 27 | uses: dotnet/nbgv@v0.4.2 28 | with: 29 | setAllVars: true 30 | - name: Setup .NET 31 | uses: actions/setup-dotnet@v4 32 | with: 33 | dotnet-version: '9.0.x' 34 | - name: Install dependencies 35 | run: dotnet restore 36 | - name: Build 37 | run: dotnet build --configuration GenerateFromSource -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 38 | - name: Test 39 | run: dotnet test --configuration GenerateFromSource --no-build --verbosity normal -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 40 | - name: Publish 41 | uses: alirezanet/publish-nuget@v3.1.0 42 | with: 43 | PROJECT_FILE_PATH: HIDDevices.Usages/HIDDevices.Usages.csproj 44 | NUGET_KEY: ${{secrets.NUGET_API_KEY}} 45 | INCLUDE_SYMBOLS: true 46 | VERSION_STATIC: ${{env.NBGV_Version}} 47 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | pull_request: 5 | branches: [ master ] 6 | 7 | paths-ignore: 8 | - '**/.md' 9 | - '**/.txt' 10 | 11 | jobs: 12 | build: 13 | 14 | runs-on: windows-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | with: 19 | fetch-depth: 0 # Avoid shallow clone so NBGV can do its work. 20 | submodules: 'recursive' 21 | - name: Set version 22 | uses: dotnet/nbgv@v0.4.2 23 | with: 24 | setAllVars: true 25 | - name: Setup .NET 26 | uses: actions/setup-dotnet@v4 27 | with: 28 | dotnet-version: '9.0.x' 29 | - name: Install dependencies 30 | run: dotnet restore 31 | - name: Build 32 | run: dotnet build --configuration Release --no-restore -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 33 | - name: Test 34 | run: dotnet test --configuration Release --no-build --verbosity normal -p:ContinuousIntegrationBuild=true -p:DeterministicSourcePaths=true 35 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevDecoder/HIDDevices/f779d27a284e1bcf5a63510a57cf60440a172655/.gitmodules -------------------------------------------------------------------------------- /DevDecoder Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevDecoder/HIDDevices/f779d27a284e1bcf5a63510a57cf60440a172655/DevDecoder Icon.png -------------------------------------------------------------------------------- /HIDDevices.Generator/AnalyzerReleases.Shipped.md: -------------------------------------------------------------------------------- 1 | ## Release 3.0 2 | 3 | ### New Rules 4 | 5 | Rule ID | Category | Severity | Notes 6 | --------|----------|----------|-------------------- 7 | HUT0001 | Generation | Info | Generation succeeded 8 | HUT00FF | Generation | Error | Generation was cancelled 9 | HUT1001 | Caching | Warning | Could not find/create HID Usage Table Caching folder. 10 | HUT1002 | Caching | Warning | Caching disabled as cache file locations could not be determined. 11 | HUT1003 | Caching | Error | PDF Not found 12 | HUT2001 | Deserialization | Error | Deserialization of the JSON HID USage Tables failed. 13 | HUT2002 | Deserialization | Error | JSON attachment not found in PDF file. 14 | HUT2003 | Deserialization | Error | Error extracting JSON attachment from PDF file. 15 | 16 | ; See https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md for explanation -------------------------------------------------------------------------------- /HIDDevices.Generator/AnalyzerReleases.Unshipped.md: -------------------------------------------------------------------------------- 1 | ### New Rules -------------------------------------------------------------------------------- /HIDDevices.Generator/HIDDevices.Generator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | latest 6 | enable 7 | true 8 | Debug;Release;GenerateFromCache;GenerateFromSource 9 | 14 | RS1036 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | 25 | 26 | 27 | 28 | 29 | 30 | $(GetTargetPathDependsOn);GetDependencyTargetPaths 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsageGenerator.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System.Collections.Generic; 5 | using Newtonsoft.Json; 6 | 7 | namespace HIDDevices.Generator; 8 | 9 | /// 10 | /// Generates HidUsages on-the-fly (according to a pattern) rather than at compile-time. 11 | /// This is used primarily by the Button/Ordinal pages, where there are 65535 UsageIds (all 'pre-defined'). 12 | /// It would be silly (and wasteful) to pre-generate all of these, so rather it is done on demand. 13 | /// 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// Name of every generated Usage. 18 | /// First valid UsageId. 19 | /// Last valid UsageId. 20 | /// Kinds to associate with generated UsageIds. 21 | [JsonObject(MemberSerialization.OptIn)] 22 | public class HidUsageGenerator(string namePrefix, ushort startUsageId, ushort endUsageId, 23 | IReadOnlyCollection kinds) 24 | { 25 | 26 | /// 27 | /// Gets the Name all generated Usages shall have. 28 | /// 29 | [JsonProperty] 30 | public string NamePrefix { get; } = namePrefix; 31 | 32 | /// 33 | /// Gets the Safe Name all generated Usages shall have. 34 | /// 35 | public string SafeNamePrefix { get; } = namePrefix.GetSafe(); 36 | 37 | /// 38 | /// Gets the first valid UsageId for this generator. All IDs between and 39 | /// (inclusive) are valid. 40 | /// 41 | [JsonProperty] 42 | public ushort StartUsageId { get; } = startUsageId; 43 | 44 | /// 45 | /// Gets the ast valid UsageId for this generator. All IDs between and 46 | /// (inclusive) are valid. 47 | /// 48 | [JsonProperty] 49 | public ushort EndUsageId { get; } = endUsageId; 50 | 51 | /// 52 | /// Gets the Usage kinds as defined the HID Usage Table. Most UsageIds will only have a single kind. 53 | /// 54 | [JsonProperty] 55 | public IReadOnlyCollection Kinds { get; } = kinds; 56 | 57 | /// 58 | public override string ToString() => $"[{StartUsageId}-{EndUsageId}]"; 59 | } 60 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsageId.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using Newtonsoft.Json; 7 | 8 | namespace HIDDevices.Generator; 9 | 10 | /// 11 | /// Represents a UsageId as defined by the HID specification. 12 | /// 13 | [JsonObject(MemberSerialization.OptIn)] 14 | public class HidUsageId 15 | { 16 | /// 17 | /// The default, undefined usage id. 18 | /// 19 | public static readonly HidUsageId Undefined = new(0, "Undefined", Array.Empty()); 20 | 21 | /// 22 | /// Initializes a new instance of the class. 23 | /// Will automatically add it to the the internal list. 24 | /// 25 | /// Id of new UsageId. 26 | /// Name of the new UsageId. 27 | /// Valid kinds for this UsageId. 28 | [JsonConstructor] 29 | private HidUsageId(ushort id, string name, IReadOnlyCollection kinds) 30 | { 31 | Id = id; 32 | Name = name; 33 | Kinds = kinds; 34 | SafeName = name.GetSafe(); 35 | } 36 | 37 | /// 38 | /// Gets the Usage Id as defined in the HID Usage Table. 39 | /// 40 | [JsonProperty] 41 | public ushort Id { get; } 42 | 43 | /// 44 | /// Gets the Usage Name as defined in the HID Usage Table. 45 | /// 46 | [JsonProperty] 47 | public string Name { get; } 48 | 49 | /// 50 | /// The C# safe version of the name. 51 | /// 52 | public string SafeName { get; internal set; } 53 | 54 | /// 55 | /// Gets the Usage kinds as defined in the HID Usage Table. 56 | /// Most UsageIds will only have a single kind. 57 | /// 58 | [JsonProperty] 59 | public IReadOnlyCollection Kinds { get; } 60 | 61 | /// 62 | public override string ToString() => $"{Name}[{Id:#,#}]"; 63 | } 64 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsageKind.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | namespace HIDDevices.Generator; 8 | 9 | /// 10 | /// Usage Kinds, as described in the HID Usage Tables. 11 | /// 12 | [JsonConverter(typeof(StringEnumConverter))] 13 | public enum HidUsageKind 14 | { 15 | // Button Kinds 16 | LC, 17 | OOC, 18 | MC, 19 | OSC, 20 | RTC, 21 | 22 | // Data Kinds 23 | Sel, 24 | SV, 25 | SF, 26 | DV, 27 | DF, 28 | BufferedBytes, 29 | 30 | // Collection Kinds. 31 | NAry, 32 | CA, 33 | CL, 34 | CP, 35 | US, 36 | UM 37 | } 38 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsagePage.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics.CodeAnalysis; 7 | using System.Linq; 8 | using Newtonsoft.Json; 9 | 10 | namespace HIDDevices.Generator; 11 | 12 | /// 13 | /// Represents a UsagePage as defined by the HID specification. 14 | /// 15 | [JsonObject(MemberSerialization.OptIn)] 16 | public class HidUsagePage 17 | { 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// Used for both Defined and Generated UsagePages by JSON serialization. 21 | /// 22 | /// Id of the new Page. 23 | /// Name of the new Page. 24 | /// Kind of UsagePage. 25 | /// The usage Ids. 26 | /// The optional generator. 27 | [JsonConstructor] 28 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", 29 | Justification = "Used during deserialization.")] 30 | private HidUsagePage(ushort id, string name, HidUsagePageKind kind, IReadOnlyList usageIds, 31 | HidUsageGenerator? usageIdGenerator) 32 | { 33 | if (string.IsNullOrEmpty(name)) 34 | { 35 | throw new ArgumentException("name can't be empty or null"); 36 | } 37 | 38 | Id = id; 39 | Name = name; 40 | Kind = kind; 41 | UsageIdGenerator = usageIdGenerator; 42 | UsageIds = Normalize(usageIds).ToArray(); 43 | SafeName = name.GetSafe(); 44 | } 45 | 46 | /// 47 | /// Gets the Kind of UsagePage this is. 48 | /// Dictates whether or are null. 49 | /// 50 | [JsonProperty] 51 | public HidUsagePageKind Kind { get; } 52 | 53 | /// 54 | /// Gets the Page Id as defined in the HID Usage Table. 55 | /// 56 | [JsonProperty] 57 | public ushort Id { get; } 58 | 59 | /// 60 | /// Gets the Page Name as defined in the HID Usage Table. 61 | /// 62 | [JsonProperty] 63 | public string Name { get; } 64 | 65 | /// 66 | /// Gets the list of known s that are associated with this . 67 | /// 68 | [JsonProperty] 69 | public IReadOnlyList UsageIds { get; } 70 | 71 | /// 72 | /// Gets the alternative to list of Ids, where s can be generated automatically. 73 | /// 74 | [JsonProperty] 75 | public HidUsageGenerator? UsageIdGenerator { get; } 76 | 77 | /// 78 | /// The C# safe version of the name. 79 | /// 80 | public string SafeName { get; internal set; } 81 | 82 | /// 83 | /// Places ids in numerical order, and ensures there is a '0' value. 84 | /// 85 | /// 86 | /// 87 | private IEnumerable Normalize(IReadOnlyList usageIds) 88 | { 89 | var safeNames = new HashSet(); 90 | var first = true; 91 | foreach (var id in usageIds.OrderBy(i => i.Id)) 92 | { 93 | if (first) 94 | { 95 | if (id.Id != 0) 96 | { 97 | safeNames.Add(HidUsageId.Undefined.SafeName); 98 | yield return HidUsageId.Undefined; 99 | } 100 | 101 | first = false; 102 | } 103 | 104 | var safeName = id.SafeName; 105 | if (safeNames.Contains(safeName)) 106 | { 107 | var suffix = 1; 108 | string newName; 109 | do 110 | { 111 | newName = safeName + ++suffix; 112 | } while (safeNames.Contains(newName)); 113 | 114 | safeName = newName; 115 | id.SafeName = newName; 116 | } 117 | 118 | safeNames.Add(safeName); 119 | yield return id; 120 | } 121 | 122 | if (first) 123 | { 124 | yield return HidUsageId.Undefined; 125 | } 126 | } 127 | 128 | /// 129 | public override string ToString() => $"{Name}[{Id:#,#}]"; 130 | } 131 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsagePageKind.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | namespace HIDDevices.Generator; 8 | 9 | /// 10 | /// Kinds of UsagePage. 11 | /// 12 | [JsonConverter(typeof(StringEnumConverter))] 13 | public enum HidUsagePageKind 14 | { 15 | /// 16 | /// All Usages within Page are pre-defined. 17 | /// 18 | Defined, 19 | 20 | /// 21 | /// Usages are generated on-demand (e.g. Ordinal/Button). 22 | /// 23 | Generated 24 | } 25 | -------------------------------------------------------------------------------- /HIDDevices.Generator/HidUsageTables.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics.CodeAnalysis; 7 | using System.Linq; 8 | using Newtonsoft.Json; 9 | 10 | // ReSharper disable UnusedMember.Global 11 | namespace HIDDevices.Generator; 12 | 13 | /// 14 | /// Container to store all UsagePages and Usages as defined by HID Usage Tables document. 15 | /// 16 | [JsonObject(MemberSerialization.OptIn)] 17 | public class HidUsageTables 18 | { 19 | /// 20 | /// Indicates an unloaded specification. 21 | /// 22 | public static HidUsageTables Empty = new(); 23 | 24 | private HidUsageTables() 25 | { 26 | UsagePages = Array.Empty(); 27 | Version = new Version(); 28 | } 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// All publicly documented UsagePages. 34 | /// Version of the HID Usage Table. 35 | /// Revision of the HID Usage Table. 36 | /// Sub-revision of the HID Usage Table. 37 | /// Date of table generation. 38 | [JsonConstructor] 39 | [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", 40 | Justification = "Used during deserialization.")] 41 | private HidUsageTables( 42 | IReadOnlyList usagePages, 43 | ushort usageTableVersion, 44 | ushort usageTableRevision, 45 | ushort usageTableSubRevisionInternal, 46 | DateTime lastGenerated) 47 | { 48 | UsagePages = usagePages.OrderBy(p => p.Id).ToArray(); 49 | 50 | UsageTableVersion = usageTableVersion; 51 | UsageTableRevision = usageTableRevision; 52 | UsageTableSubRevisionInternal = usageTableSubRevisionInternal; 53 | Version = new Version(UsageTableVersion, UsageTableRevision, usageTableSubRevisionInternal); 54 | 55 | LastGenerated = lastGenerated; 56 | } 57 | 58 | /// 59 | /// Gets the Version of the table. 60 | /// 61 | [JsonProperty] 62 | public ushort UsageTableVersion { get; } 63 | 64 | /// 65 | /// Gets the Revision of the table. 66 | /// 67 | [JsonProperty] 68 | public ushort UsageTableRevision { get; } 69 | 70 | /// 71 | /// Gets the Sub-revision of the table. 72 | /// 73 | [JsonProperty] 74 | public ushort UsageTableSubRevisionInternal { get; } 75 | 76 | /// 77 | /// The specification version 78 | /// 79 | public Version Version { get; } 80 | 81 | /// 82 | /// Gets the date the table was generated. 83 | /// 84 | [JsonProperty] 85 | public DateTime LastGenerated { get; } 86 | 87 | /// 88 | /// Gets the UsagePages of the table. 89 | /// 90 | [JsonProperty] 91 | public IReadOnlyList UsagePages { get; } 92 | } 93 | -------------------------------------------------------------------------------- /HIDDevices.Sample/HIDDevices.Sample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | enable 7 | HIDCSample 8 | HIDDevices.Sample 9 | Debug;Release;GenerateFromCache;GenerateFromSource 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | True 25 | True 26 | Resources.resx 27 | 28 | 29 | 30 | 31 | 32 | ResXFileCodeGenerator 33 | Resources.Designer.cs 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /HIDDevices.Sample/ISample.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System.Collections.Generic; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace HIDDevices.Sample; 9 | 10 | public interface ISample 11 | { 12 | string FullName { get; } 13 | string Description { get; } 14 | IReadOnlyCollection ShortNames { get; } 15 | Task ExecuteAsync(CancellationToken token = default); 16 | } 17 | -------------------------------------------------------------------------------- /HIDDevices.Sample/Program.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Resources; 9 | using System.Threading.Tasks; 10 | 11 | [assembly: NeutralResourcesLanguage("en-GB")] 12 | [assembly: 13 | SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "This is sample code")] 14 | 15 | namespace HIDDevices.Sample; 16 | 17 | internal static class Program 18 | { 19 | private static async Task Main(string[] args) 20 | { 21 | var assembly = Assembly.GetExecutingAssembly(); 22 | 23 | var samples = assembly 24 | .GetTypes() 25 | .Where(t => !t.IsAbstract && 26 | (t.IsValueType || 27 | (t.GetInterfaces().Contains(typeof(ISample)) && 28 | t.GetConstructor(Type.EmptyTypes) != null))) 29 | .Select(Activator.CreateInstance) 30 | .OfType() 31 | .ToArray(); 32 | 33 | ISample? sample; 34 | if (args.Length != 1 || 35 | (sample = Array.Find(samples, s => s.ShortNames.Contains(args[0]))) is null) 36 | { 37 | var assemblyName = assembly.GetName().Name; 38 | // We appear to have a cry for help! 39 | Console.WriteLine(Resources.SampleExecutor, assemblyName); 40 | Console.WriteLine(); 41 | 42 | do 43 | { 44 | Console.WriteLine(Resources.SelectSample); 45 | 46 | // Create instances of all sample classes 47 | foreach (var s in samples) 48 | { 49 | Console.WriteLine( 50 | Resources.SampleDescription, Environment.NewLine, 51 | string.Join('|', s.ShortNames), 52 | s.FullName, 53 | s.Description); 54 | } 55 | 56 | if (!Environment.UserInteractive) 57 | { 58 | return; 59 | } 60 | 61 | var option = Console.ReadLine(); 62 | sample = Array.Find(samples, s => s.ShortNames.Contains(option)); 63 | } while (sample is null); 64 | } 65 | 66 | Console.WriteLine(Resources.RunningSample, sample.FullName); 67 | Console.WriteLine(); 68 | await sample.ExecuteAsync().ConfigureAwait(false); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /HIDDevices.Sample/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "HIDDevices.Sample": { 4 | "commandName": "Project" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /HIDDevices.Sample/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // 5 | // Changes to this file may cause incorrect behavior and will be lost if 6 | // the code is regenerated. 7 | // 8 | //------------------------------------------------------------------------------ 9 | 10 | namespace HIDDevices.Sample { 11 | using System; 12 | 13 | 14 | /// 15 | /// A strongly-typed resource class, for looking up localized strings, etc. 16 | /// 17 | // This class was auto-generated by the StronglyTypedResourceBuilder 18 | // class via a tool like ResGen or Visual Studio. 19 | // To add or remove a member, edit your .ResX file then rerun ResGen 20 | // with the /str option, or rebuild your VS project. 21 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] 22 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 23 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 24 | internal class Resources { 25 | 26 | private static global::System.Resources.ResourceManager resourceMan; 27 | 28 | private static global::System.Globalization.CultureInfo resourceCulture; 29 | 30 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 31 | internal Resources() { 32 | } 33 | 34 | /// 35 | /// Returns the cached ResourceManager instance used by this class. 36 | /// 37 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 38 | internal static global::System.Resources.ResourceManager ResourceManager { 39 | get { 40 | if (object.ReferenceEquals(resourceMan, null)) { 41 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HIDDevices.Sample.Resources", typeof(Resources).Assembly); 42 | resourceMan = temp; 43 | } 44 | return resourceMan; 45 | } 46 | } 47 | 48 | /// 49 | /// Overrides the current thread's CurrentUICulture property for all 50 | /// resource lookups using this strongly typed resource class. 51 | /// 52 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 53 | internal static global::System.Globalization.CultureInfo Culture { 54 | get { 55 | return resourceCulture; 56 | } 57 | set { 58 | resourceCulture = value; 59 | } 60 | } 61 | 62 | /// 63 | /// Looks up a localized string similar to Running {0}.... 64 | /// 65 | internal static string RunningSample { 66 | get { 67 | return ResourceManager.GetString("RunningSample", resourceCulture); 68 | } 69 | } 70 | 71 | /// 72 | /// Looks up a localized string similar to [{1}]{0} {2}{0} {3}{0}. 73 | /// 74 | internal static string SampleDescription { 75 | get { 76 | return ResourceManager.GetString("SampleDescription", resourceCulture); 77 | } 78 | } 79 | 80 | /// 81 | /// Looks up a localized string similar to {0} - Sample executor. 82 | /// 83 | internal static string SampleExecutor { 84 | get { 85 | return ResourceManager.GetString("SampleExecutor", resourceCulture); 86 | } 87 | } 88 | 89 | /// 90 | /// Looks up a localized string similar to Please select one of the following samples to run.. 91 | /// 92 | internal static string SelectSample { 93 | get { 94 | return ResourceManager.GetString("SelectSample", resourceCulture); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /HIDDevices.Sample/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 61 | 62 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | text/microsoft-resx 92 | 93 | 94 | 1.3 95 | 96 | 97 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, 98 | PublicKeyToken=b77a5c561934e089 99 | 100 | 101 | 102 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, 103 | PublicKeyToken=b77a5c561934e089 104 | 105 | 106 | 107 | {0} - Sample executor 108 | 109 | 110 | Please select one of the following samples to run. 111 | 112 | 113 | Running {0}... 114 | 115 | 116 | [{1}]{0} {2}{0} {3}{0} 117 | 118 | -------------------------------------------------------------------------------- /HIDDevices.Sample/Sample.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Globalization; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace HIDDevices.Sample; 13 | 14 | public abstract class Sample : ISample 15 | { 16 | private readonly SimpleConsoleLogger _logger; 17 | private readonly HashSet _shortNames; 18 | 19 | protected Sample(string? fullName = null, params string[] shortNames) 20 | { 21 | FullName = fullName ?? GetFullName(GetType().Name); 22 | 23 | _shortNames = shortNames.Length > 0 ? new HashSet(shortNames) : GetShortNames(FullName); 24 | _logger = new SimpleConsoleLogger(LogLevel.Information, GetType().Name); 25 | } 26 | 27 | protected ILogger Logger => _logger; 28 | 29 | public LogLevel LogLevel { get => _logger.LogLevel; set => _logger.LogLevel = value; } 30 | 31 | /// 32 | public string FullName { get; } 33 | 34 | /// 35 | public IReadOnlyCollection ShortNames => _shortNames; 36 | 37 | /// 38 | public virtual Task ExecuteAsync(CancellationToken token = default) => Task.Run(Execute, token); 39 | 40 | /// 41 | public abstract string Description { get; } 42 | 43 | /// 44 | /// Execute the example synchronously. 45 | /// 46 | protected virtual void Execute() { } 47 | 48 | public static ILogger CreateLogger(LogLevel logLevel = LogLevel.Information) => 49 | new SimpleConsoleLogger(logLevel); 50 | 51 | /// 52 | /// Gets a friendly full name 53 | /// 54 | /// 55 | /// 56 | protected static string GetFullName(string typeName) 57 | { 58 | var builder = new StringBuilder(typeName.Length + 5); 59 | var first = true; 60 | foreach (var c in typeName) 61 | { 62 | if (first) 63 | { 64 | first = false; 65 | } 66 | else if (char.IsUpper(c)) 67 | { 68 | builder.Append(' '); 69 | } 70 | 71 | builder.Append(c); 72 | } 73 | 74 | var fullName = builder.ToString(); 75 | if (fullName.EndsWith("Sample", StringComparison.InvariantCultureIgnoreCase)) 76 | { 77 | fullName = fullName[..^6].TrimEnd(); 78 | } 79 | 80 | return fullName; 81 | } 82 | 83 | /// 84 | /// Gets some short names based on the first word and initials. 85 | /// 86 | /// The full name of the sample. 87 | /// An array of short names. 88 | protected static HashSet GetShortNames(string fullName) 89 | { 90 | var shortNames = new HashSet(StringComparer.InvariantCultureIgnoreCase); 91 | var initials = new StringBuilder(); 92 | var word = new StringBuilder(); 93 | var titleCase = new StringBuilder(); 94 | var afterSpace = true; 95 | var firstWord = true; 96 | foreach (var c in fullName) 97 | { 98 | if (char.GetUnicodeCategory(c) == UnicodeCategory.SpaceSeparator) 99 | { 100 | afterSpace = true; 101 | firstWord = false; 102 | continue; 103 | } 104 | 105 | if (afterSpace) 106 | { 107 | afterSpace = false; 108 | var ch = char.ToUpperInvariant(c); 109 | initials.Append(ch); 110 | titleCase.Append(ch); 111 | } 112 | else 113 | { 114 | titleCase.Append(c); 115 | } 116 | 117 | if (firstWord) 118 | { 119 | word.Append(c); 120 | } 121 | } 122 | 123 | shortNames.Add(initials.ToString(0, 1)); 124 | if (initials.Length > 1) 125 | { 126 | shortNames.Add(initials.ToString()); 127 | } 128 | 129 | shortNames.Add(word.ToString()); 130 | 131 | if (titleCase.Length < 10) 132 | { 133 | shortNames.Add(titleCase.ToString()); 134 | } 135 | 136 | return shortNames; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /HIDDevices.Sample/Samples/GameLoopSample.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading; 8 | using DevDecoder.HIDDevices; 9 | using DevDecoder.HIDDevices.Controllers; 10 | using Microsoft.Extensions.Logging; 11 | 12 | namespace HIDDevices.Sample.Samples; 13 | 14 | public class GameLoopSample : Sample 15 | { 16 | /// 17 | public override string Description => 18 | "Demonstrates a classic synchronous game loop."; 19 | 20 | /// 21 | protected override void Execute() 22 | { 23 | // Create a singleton instance of the controllers object, that we should dispose 24 | // on closing the game, here we use a using block, but can obviously call controllers.Dispose() 25 | using var devices = new Devices(CreateLogger()); 26 | 27 | Logger.LogInformation("Press A Button to exit!"); 28 | 29 | // Holds a reference to the current gamepad, which is set asynchronously as they are detected. 30 | Gamepad? gamepad = null; 31 | var batch = 0; 32 | 33 | // Controller to any gamepads as they are found 34 | using var subscription = devices.Controllers().Subscribe(g => 35 | { 36 | // If we already have a connected gamepad ignore any more. 37 | // ReSharper disable once AccessToDisposedClosure 38 | if (gamepad?.IsConnected == true) 39 | { 40 | return; 41 | } 42 | 43 | if (g.Name.Contains("xbox ", StringComparison.InvariantCultureIgnoreCase)) 44 | { 45 | Logger.LogWarning( 46 | $"{g.Name} found! Unfortunately, it appears XInput-compatible HID device driver only transmits events from the HID device whilst the current process has a focussed window, so console applications/background services cannot detect button presses. Please try a different controller."); 47 | return; 48 | } 49 | 50 | // Assign this gamepad and connect to it. 51 | gamepad = g; 52 | g.Connect(); 53 | batch = 0; 54 | Logger.LogInformation($"{gamepad.Name} found! Following controls were mapped:"); 55 | foreach (var (control, infos) in g.Mapping) 56 | { 57 | Logger.LogInformation( 58 | // ReSharper disable once SuspiciousTypeConversion.Global 59 | $" {Usage.GetName(control.Usages)} => {string.Join(", ", infos.Select(info => info.PropertyName))}"); 60 | } 61 | }); 62 | 63 | var timestamp = 0L; 64 | try 65 | { 66 | // Our 'game loop' 67 | while (true) 68 | { 69 | // Sleep to simulate a game loop. 70 | Thread.Sleep(15); 71 | 72 | // If we haven't got a gamepad, or the current one isn't connected, wait for a connected gamepad. 73 | var currentGamepad = gamepad; 74 | if (currentGamepad?.IsConnected != true) { continue; } 75 | 76 | // Look for any changes since the last detected change. 77 | var changes = currentGamepad.ChangesSince(timestamp); 78 | if (changes.Count > 0) 79 | { 80 | var logBuilder = new StringBuilder(); 81 | 82 | logBuilder.Append("Batch ").Append(++batch).AppendLine(); 83 | foreach (var value in changes) 84 | { 85 | // We should update our timestamp to the last change we see. 86 | if (timestamp < value.Timestamp) 87 | { 88 | timestamp = value.Timestamp; 89 | } 90 | 91 | var valueStr = value.Value switch 92 | { 93 | bool b => b ? "Pressed" : "Not Pressed", 94 | double d => d.ToString("F3"), 95 | null => "", 96 | _ => value.Value.ToString() 97 | }; 98 | logBuilder.Append(" ") 99 | .Append(value.PropertyName) 100 | .Append(": ") 101 | .Append(valueStr) 102 | .Append(" (") 103 | .AppendFormat("{0:F3}", value.Elapsed.TotalMilliseconds).AppendLine("ms)"); 104 | } 105 | 106 | Logger.LogInformation(logBuilder.ToString()); 107 | } 108 | 109 | // Or directly access controls 110 | if (currentGamepad.AButton) 111 | { 112 | Logger.LogInformation("A Button pressed, finishing."); 113 | return; 114 | } 115 | } 116 | } 117 | finally 118 | { 119 | // Ensure gamepad connection is disposed to stop listening to the gamepad 120 | if (gamepad != null) 121 | { 122 | gamepad.Dispose(); 123 | Logger.LogInformation($"{gamepad.Device.Name} disconnected!"); 124 | } 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /HIDDevices.Sample/SimpleConsoleLogger.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Reactive.Disposables; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace HIDDevices.Sample; 9 | 10 | public class SimpleConsoleLogger(LogLevel logLevel, string? name = null) : ILogger 11 | { 12 | public readonly string Name = name ?? typeof(T).Name; 13 | 14 | public LogLevel LogLevel { get; set; } = logLevel; 15 | 16 | /// 17 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, 18 | Func formatter) 19 | { 20 | if (!IsEnabled(logLevel)) 21 | { 22 | return; 23 | } 24 | 25 | var message = formatter(state, exception); 26 | 27 | if (!string.IsNullOrEmpty(message)) 28 | { 29 | Console.WriteLine(message); 30 | } 31 | } 32 | 33 | /// 34 | public bool IsEnabled(LogLevel logLevel) => LogLevel <= logLevel; 35 | 36 | /// 37 | public IDisposable BeginScope(TState state) where TState : notnull => Disposable.Empty; 38 | } 39 | -------------------------------------------------------------------------------- /HIDDevices.Test/HIDDevices.Test.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net8.0 4 | false 5 | Debug;Release;GenerateFromCache;GenerateFromSource 6 | 7 | 8 | 9 | 10 | 11 | all 12 | runtime; build; native; contentfiles; analyzers; buildtransitive 13 | 14 | 15 | all 16 | runtime; build; native; contentfiles; analyzers; buildtransitive 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /HIDDevices.Test/Tests.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Linq; 7 | using System.Reactive.Linq; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using DevDecoder.HIDDevices; 11 | using DevDecoder.HIDDevices.Usages; 12 | using Microsoft.Extensions.Logging; 13 | using Xunit; 14 | using Xunit.Abstractions; 15 | 16 | [assembly: 17 | SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "This is sample code")] 18 | 19 | namespace HIDDevices.Test; 20 | 21 | public class Tests 22 | { 23 | public Tests(ITestOutputHelper outputHelper) 24 | { 25 | OutputHelper = outputHelper; 26 | Logger = OutputHelper.ToLogger(); 27 | } 28 | 29 | private ITestOutputHelper OutputHelper { get; } 30 | private ILogger Logger { get; } 31 | 32 | [Fact] 33 | public void EventAllTest() 34 | { 35 | Assert.NotEmpty(Event.All); 36 | Assert.Equal(Event.All.Count, Event.All.Select(e => e.Id).Distinct().Count()); 37 | // ReSharper disable ParameterOnlyUsedForPreconditionCheck.Local 38 | Assert.DoesNotContain(Event.All, e => string.IsNullOrWhiteSpace(e.Format)); 39 | Assert.DoesNotContain(Event.All, e => string.IsNullOrWhiteSpace(e.Description)); 40 | // ReSharper restore ParameterOnlyUsedForPreconditionCheck.Local 41 | 42 | // The library provides fully described Event IDs, with localisable resources, for easy filtering of logs. 43 | // The full list of events can be found in the Event.All collection. 44 | foreach (var @event in Event.All) 45 | { 46 | Logger.LogInformation(@event, @event.Description); 47 | } 48 | } 49 | 50 | [Fact] 51 | public async Task TestLoadAsync() 52 | { 53 | var refreshCount = 0; 54 | using var devices = new Devices(OutputHelper.ToLogger()); 55 | using var _ = devices.Refreshing 56 | .Do(r => Logger.LogInformation($"Refreshing is {r}")) 57 | .Where(r => !r) 58 | // ReSharper disable once VariableHidesOuterVariable 59 | .Subscribe(_ => Interlocked.Increment(ref refreshCount)); 60 | 61 | Assert.Equal(0, refreshCount); 62 | var initial = await devices.LoadAsync().ConfigureAwait(true); 63 | OutputHelper.WriteLine($"{initial.Count} controllers"); 64 | Assert.Equal(1, refreshCount); 65 | 66 | // Repeated calls to LoadAsync should complete immediately, giving the same result 67 | // (assuming there's no change in the underlying devices which triggers an auto-refresh) 68 | var repeat = await devices.LoadAsync().ConfigureAwait(true); 69 | Assert.Equal(initial, repeat); 70 | Assert.Equal(1, refreshCount); 71 | } 72 | 73 | [Fact] 74 | public void TestUndefinedUsage() 75 | { 76 | var usage = Usage.Get(0xffff); 77 | Assert.Equal("Reserved (0x0000) - Undefined (0xFFFF)", usage.ToString()); 78 | } 79 | 80 | [Fact] 81 | public void TestControlAttribute() 82 | { 83 | // Confirm that the enum and raw value are identical. 84 | var attr1 = new ControlAttribute(ButtonPage.Button15); 85 | var attr2 = new ControlAttribute(0x00090010); 86 | Assert.Single(attr1.Usages); 87 | Assert.Single(attr2.Usages); 88 | Assert.Equal(attr1.Usages[0], attr2.Usages[0]); 89 | 90 | // Confirm that a user defined ID is accepted. 91 | var attr3 = new ControlAttribute(0x00090011); 92 | Usage usage = attr3.Usages[0]; 93 | Assert.Equal(UsagePage.Button, usage.Page); 94 | Assert.Equal(17, usage.Id); 95 | 96 | Logger.LogInformation($"User defined usage: {usage}"); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/ArcadeUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Arcade Usage Page. 19 | // 20 | public sealed class ArcadeUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Arcade Usage Page. 24 | // 25 | public static readonly ArcadeUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private ArcadeUsagePage() : base(0x0091, "Arcade") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "General Purpose IO Card", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Coin Door", UsageTypes.CA); 42 | case 0x0003: return new Usage(this, id, "Watchdog Timer", UsageTypes.CA); 43 | case 0x0030: return new Usage(this, id, "General Purpose Analog Input State", UsageTypes.DV); 44 | case 0x0031: return new Usage(this, id, "General Purpose Digital Input State", UsageTypes.DV); 45 | case 0x0032: return new Usage(this, id, "General Purpose Optical Input State", UsageTypes.DV); 46 | case 0x0033: return new Usage(this, id, "General Purpose Digital Output State", UsageTypes.DV); 47 | case 0x0034: return new Usage(this, id, "Number of Coin Doors", UsageTypes.DV); 48 | case 0x0035: return new Usage(this, id, "Coin Drawer Drop Count", UsageTypes.DV); 49 | case 0x0036: return new Usage(this, id, "Coin Drawer Start", UsageTypes.OOC); 50 | case 0x0037: return new Usage(this, id, "Coin Drawer Service", UsageTypes.OOC); 51 | case 0x0038: return new Usage(this, id, "Coin Drawer Tilt", UsageTypes.OOC); 52 | case 0x0039: return new Usage(this, id, "Coin Door Test", UsageTypes.OOC); 53 | case 0x0040: return new Usage(this, id, "Coin Door Lockout", UsageTypes.OOC); 54 | case 0x0041: return new Usage(this, id, "Watchdog Timeout", UsageTypes.DV); 55 | case 0x0042: return new Usage(this, id, "Watchdog Action", UsageTypes.NAry); 56 | case 0x0043: return new Usage(this, id, "Watchdog Reboot", UsageTypes.Sel); 57 | case 0x0044: return new Usage(this, id, "Watchdog Restart", UsageTypes.Sel); 58 | case 0x0045: return new Usage(this, id, "Alarm Input", UsageTypes.DV); 59 | case 0x0046: return new Usage(this, id, "Coin Door Counter", UsageTypes.OOC); 60 | case 0x0047: return new Usage(this, id, "I/O Direction Mapping", UsageTypes.DV); 61 | case 0x0048: return new Usage(this, id, "Set I/O Direction Mapping", UsageTypes.DV); 62 | case 0x0049: return new Usage(this, id, "Extended Optical Input State", UsageTypes.DV); 63 | case 0x004a: return new Usage(this, id, "Pin Pad Input State", UsageTypes.DV); 64 | case 0x004b: return new Usage(this, id, "Pin Pad Status", UsageTypes.DV); 65 | case 0x004c: return new Usage(this, id, "Pin Pad Output", UsageTypes.OOC); 66 | case 0x004d: return new Usage(this, id, "Pin Pad Command", UsageTypes.DV); 67 | } 68 | 69 | return base.CreateUsage(id); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/BrailleDisplayUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Braille Display Usage Page. 19 | // 20 | public sealed class BrailleDisplayUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Braille Display Usage Page. 24 | // 25 | public static readonly BrailleDisplayUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private BrailleDisplayUsagePage() : base(0x0041, "Braille Display") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Braille Display", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Braille Row", UsageTypes.NAry); 42 | case 0x0003: return new Usage(this, id, "8 Dot Braille Cell", UsageTypes.DV); 43 | case 0x0004: return new Usage(this, id, "6 Dot Braille Cell", UsageTypes.DV); 44 | case 0x0005: return new Usage(this, id, "Number of Braille Cells", UsageTypes.DV); 45 | case 0x0006: return new Usage(this, id, "Screen Reader Control", UsageTypes.NAry); 46 | case 0x0007: return new Usage(this, id, "Screen Reader Identifier", UsageTypes.DV); 47 | case 0x00fa: return new Usage(this, id, "Router Set 1", UsageTypes.NAry); 48 | case 0x00fb: return new Usage(this, id, "Router Set 2", UsageTypes.NAry); 49 | case 0x00fc: return new Usage(this, id, "Router Set 3", UsageTypes.NAry); 50 | case 0x0100: return new Usage(this, id, "Router Key", UsageTypes.Sel); 51 | case 0x0101: return new Usage(this, id, "Row Router Key", UsageTypes.Sel); 52 | case 0x0200: return new Usage(this, id, "Braille Buttons", UsageTypes.NAry); 53 | case 0x0201: return new Usage(this, id, "Braille Keyboard Dot 1", UsageTypes.Sel); 54 | case 0x0202: return new Usage(this, id, "Braille Keyboard Dot 2", UsageTypes.Sel); 55 | case 0x0203: return new Usage(this, id, "Braille Keyboard Dot 3", UsageTypes.Sel); 56 | case 0x0204: return new Usage(this, id, "Braille Keyboard Dot 4", UsageTypes.Sel); 57 | case 0x0205: return new Usage(this, id, "Braille Keyboard Dot 5", UsageTypes.Sel); 58 | case 0x0206: return new Usage(this, id, "Braille Keyboard Dot 6", UsageTypes.Sel); 59 | case 0x0207: return new Usage(this, id, "Braille Keyboard Dot 7", UsageTypes.Sel); 60 | case 0x0208: return new Usage(this, id, "Braille Keyboard Dot 8", UsageTypes.Sel); 61 | case 0x0209: return new Usage(this, id, "Braille Keyboard Space", UsageTypes.Sel); 62 | case 0x020a: return new Usage(this, id, "Braille Keyboard Left Space", UsageTypes.Sel); 63 | case 0x020b: return new Usage(this, id, "Braille Keyboard Right Space", UsageTypes.Sel); 64 | case 0x020c: return new Usage(this, id, "Braille Face Controls", UsageTypes.NAry); 65 | case 0x020d: return new Usage(this, id, "Braille Left Controls", UsageTypes.NAry); 66 | case 0x020e: return new Usage(this, id, "Braille Right Controls", UsageTypes.NAry); 67 | case 0x020f: return new Usage(this, id, "Braille Top Controls", UsageTypes.NAry); 68 | case 0x0210: return new Usage(this, id, "Braille Joystick Center", UsageTypes.Sel); 69 | case 0x0211: return new Usage(this, id, "Braille Joystick Up", UsageTypes.Sel); 70 | case 0x0212: return new Usage(this, id, "Braille Joystick Down", UsageTypes.Sel); 71 | case 0x0213: return new Usage(this, id, "Braille Joystick Left", UsageTypes.Sel); 72 | case 0x0214: return new Usage(this, id, "Braille Joystick Right", UsageTypes.Sel); 73 | case 0x0215: return new Usage(this, id, "Braille D-Pad Center", UsageTypes.Sel); 74 | case 0x0216: return new Usage(this, id, "Braille D-Pad Up", UsageTypes.Sel); 75 | case 0x0217: return new Usage(this, id, "Braille D-Pad Down", UsageTypes.Sel); 76 | case 0x0218: return new Usage(this, id, "Braille D-Pad Left", UsageTypes.Sel); 77 | case 0x0219: return new Usage(this, id, "Braille D-Pad Right", UsageTypes.Sel); 78 | case 0x021a: return new Usage(this, id, "Braille Pan Left", UsageTypes.Sel); 79 | case 0x021b: return new Usage(this, id, "Braille Pan Right", UsageTypes.Sel); 80 | case 0x021c: return new Usage(this, id, "Braille Rocker Up", UsageTypes.Sel); 81 | case 0x021d: return new Usage(this, id, "Braille Rocker Down", UsageTypes.Sel); 82 | case 0x021e: return new Usage(this, id, "Braille Rocker Press", UsageTypes.Sel); 83 | } 84 | 85 | return base.CreateUsage(id); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/ButtonPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Button Usage Page. 17 | // 18 | [Description("Button Usage Page")] 19 | public enum ButtonPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00090000, 26 | 27 | // Range: 0x0001 -> 0xffff 28 | 29 | // 30 | // Button 0 Usage. 31 | // 32 | [Description("Button 0")] 33 | Button0 = 0x00090001, 34 | 35 | // 36 | // Button 1 Usage. 37 | // 38 | [Description("Button 1")] 39 | Button1 = 0x00090002, 40 | 41 | // 42 | // Button 2 Usage. 43 | // 44 | [Description("Button 2")] 45 | Button2 = 0x00090003, 46 | 47 | // 48 | // Button 3 Usage. 49 | // 50 | [Description("Button 3")] 51 | Button3 = 0x00090004, 52 | 53 | // 54 | // Button 4 Usage. 55 | // 56 | [Description("Button 4")] 57 | Button4 = 0x00090005, 58 | 59 | // 60 | // Button 5 Usage. 61 | // 62 | [Description("Button 5")] 63 | Button5 = 0x00090006, 64 | 65 | // 66 | // Button 6 Usage. 67 | // 68 | [Description("Button 6")] 69 | Button6 = 0x00090007, 70 | 71 | // 72 | // Button 7 Usage. 73 | // 74 | [Description("Button 7")] 75 | Button7 = 0x00090008, 76 | 77 | // 78 | // Button 8 Usage. 79 | // 80 | [Description("Button 8")] 81 | Button8 = 0x00090009, 82 | 83 | // 84 | // Button 9 Usage. 85 | // 86 | [Description("Button 9")] 87 | Button9 = 0x0009000a, 88 | 89 | // 90 | // Button 10 Usage. 91 | // 92 | [Description("Button 10")] 93 | Button10 = 0x0009000b, 94 | 95 | // 96 | // Button 11 Usage. 97 | // 98 | [Description("Button 11")] 99 | Button11 = 0x0009000c, 100 | 101 | // 102 | // Button 12 Usage. 103 | // 104 | [Description("Button 12")] 105 | Button12 = 0x0009000d, 106 | 107 | // 108 | // Button 13 Usage. 109 | // 110 | [Description("Button 13")] 111 | Button13 = 0x0009000e, 112 | 113 | // 114 | // Button 14 Usage. 115 | // 116 | [Description("Button 14")] 117 | Button14 = 0x0009000f, 118 | 119 | // 120 | // Button 15 Usage. 121 | // 122 | [Description("Button 15")] 123 | Button15 = 0x00090010 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/ButtonUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Button Usage Page. 19 | // 20 | public sealed class ButtonUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Button Usage Page. 24 | // 25 | public static readonly ButtonUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private ButtonUsagePage() : base(0x0009, "Button") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Button 0", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 41 | case 0x0002: return new Usage(this, id, "Button 1", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 42 | case 0x0003: return new Usage(this, id, "Button 2", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 43 | case 0x0004: return new Usage(this, id, "Button 3", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 44 | case 0x0005: return new Usage(this, id, "Button 4", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 45 | case 0x0006: return new Usage(this, id, "Button 5", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 46 | case 0x0007: return new Usage(this, id, "Button 6", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 47 | case 0x0008: return new Usage(this, id, "Button 7", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 48 | case 0x0009: return new Usage(this, id, "Button 8", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 49 | case 0x000a: return new Usage(this, id, "Button 9", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 50 | case 0x000b: return new Usage(this, id, "Button 10", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 51 | case 0x000c: return new Usage(this, id, "Button 11", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 52 | case 0x000d: return new Usage(this, id, "Button 12", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 53 | case 0x000e: return new Usage(this, id, "Button 13", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 54 | case 0x000f: return new Usage(this, id, "Button 14", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 55 | case 0x0010: return new Usage(this, id, "Button 15", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 56 | } 57 | var n = (ushort)(id-0x0001); 58 | if (id >= 0x0011 || id <= 0xffff) return new Usage(this, id, $"Button {n}", UsageTypes.Sel|UsageTypes.OOC|UsageTypes.MC|UsageTypes.OSC); 59 | 60 | return base.CreateUsage(id); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/CameraControlPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Camera Control Usage Page. 17 | // 18 | [Description("Camera Control Usage Page")] 19 | public enum CameraControlPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00900000, 26 | 27 | // 28 | // Camera Auto-focus Usage. 29 | // 30 | [Description("Camera Auto-focus")] 31 | CameraAutofocus = 0x00900020, 32 | 33 | // 34 | // Camera Shutter Usage. 35 | // 36 | [Description("Camera Shutter")] 37 | CameraShutter = 0x00900021 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/CameraControlUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Camera Control Usage Page. 19 | // 20 | public sealed class CameraControlUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Camera Control Usage Page. 24 | // 25 | public static readonly CameraControlUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private CameraControlUsagePage() : base(0x0090, "Camera Control") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0020: return new Usage(this, id, "Camera Auto-focus", UsageTypes.OSC); 41 | case 0x0021: return new Usage(this, id, "Camera Shutter", UsageTypes.OSC); 42 | } 43 | 44 | return base.CreateUsage(id); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/EyeAndHeadTrackersUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Eye and Head Trackers Usage Page. 19 | // 20 | public sealed class EyeAndHeadTrackersUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Eye and Head Trackers Usage Page. 24 | // 25 | public static readonly EyeAndHeadTrackersUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private EyeAndHeadTrackersUsagePage() : base(0x0012, "Eye and Head Trackers") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Eye Tracker", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Head Tracker", UsageTypes.CA); 42 | case 0x0010: return new Usage(this, id, "Tracking Data", UsageTypes.CP); 43 | case 0x0011: return new Usage(this, id, "Capabilities", UsageTypes.CL); 44 | case 0x0012: return new Usage(this, id, "Configuration", UsageTypes.CL); 45 | case 0x0013: return new Usage(this, id, "Status", UsageTypes.CL); 46 | case 0x0014: return new Usage(this, id, "Control", UsageTypes.CL); 47 | case 0x0020: return new Usage(this, id, "Sensor Timestamp", UsageTypes.DV); 48 | case 0x0021: return new Usage(this, id, "Position X", UsageTypes.DV); 49 | case 0x0022: return new Usage(this, id, "Position Y", UsageTypes.DV); 50 | case 0x0023: return new Usage(this, id, "Position Z", UsageTypes.DV); 51 | case 0x0024: return new Usage(this, id, "Gaze Point", UsageTypes.CP); 52 | case 0x0025: return new Usage(this, id, "Left Eye Position", UsageTypes.CP); 53 | case 0x0026: return new Usage(this, id, "Right Eye Position", UsageTypes.CP); 54 | case 0x0027: return new Usage(this, id, "Head Position", UsageTypes.CP); 55 | case 0x0028: return new Usage(this, id, "Head Direction Point", UsageTypes.CP); 56 | case 0x0029: return new Usage(this, id, "Rotation about X axis", UsageTypes.DV); 57 | case 0x002a: return new Usage(this, id, "Rotation about Y axis", UsageTypes.DV); 58 | case 0x002b: return new Usage(this, id, "Rotation about Z axis", UsageTypes.DV); 59 | case 0x0100: return new Usage(this, id, "Tracker Quality", UsageTypes.SV); 60 | case 0x0101: return new Usage(this, id, "Minimum Tracking Distance", UsageTypes.SV); 61 | case 0x0102: return new Usage(this, id, "Optimum Tracking Distance", UsageTypes.SV); 62 | case 0x0103: return new Usage(this, id, "Maximum Tracking Distance", UsageTypes.SV); 63 | case 0x0104: return new Usage(this, id, "Maximum Screen Plane Width", UsageTypes.SV); 64 | case 0x0105: return new Usage(this, id, "Maximum Screen Plane Height", UsageTypes.SV); 65 | case 0x0200: return new Usage(this, id, "Display Manufacturer ID", UsageTypes.SV); 66 | case 0x0201: return new Usage(this, id, "Display Product ID", UsageTypes.SV); 67 | case 0x0202: return new Usage(this, id, "Display Serial Number", UsageTypes.SV); 68 | case 0x0203: return new Usage(this, id, "Display Manufacturer Date", UsageTypes.SV); 69 | case 0x0204: return new Usage(this, id, "Calibrated Screen Width", UsageTypes.SV); 70 | case 0x0205: return new Usage(this, id, "Calibrated Screen Height", UsageTypes.SV); 71 | case 0x0300: return new Usage(this, id, "Sampling Frequency", UsageTypes.DV); 72 | case 0x0301: return new Usage(this, id, "Configuration Status", UsageTypes.DV); 73 | case 0x0400: return new Usage(this, id, "Device Mode Request", UsageTypes.DV); 74 | } 75 | 76 | return base.CreateUsage(id); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/FIDOAlliancePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // FIDO Alliance Usage Page. 17 | // 18 | [Description("FIDO Alliance Usage Page")] 19 | public enum FIDOAlliancePage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0xf1d00000, 26 | 27 | // 28 | // U2F Authenticator Device Usage. 29 | // 30 | [Description("U2F Authenticator Device")] 31 | U2FAuthenticatorDevice = 0xf1d00001, 32 | 33 | // 34 | // Input Report Data Usage. 35 | // 36 | [Description("Input Report Data")] 37 | InputReportData = 0xf1d00020, 38 | 39 | // 40 | // Output Report Data Usage. 41 | // 42 | [Description("Output Report Data")] 43 | OutputReportData = 0xf1d00021 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/FIDOAllianceUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // FIDO Alliance Usage Page. 19 | // 20 | public sealed class FIDOAllianceUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of FIDO Alliance Usage Page. 24 | // 25 | public static readonly FIDOAllianceUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private FIDOAllianceUsagePage() : base(0xf1d0, "FIDO Alliance") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "U2F Authenticator Device", UsageTypes.CA); 41 | case 0x0020: return new Usage(this, id, "Input Report Data", UsageTypes.DV); 42 | case 0x0021: return new Usage(this, id, "Output Report Data", UsageTypes.DV); 43 | } 44 | 45 | return base.CreateUsage(id); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/GameControlsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Game Controls Usage Page. 19 | // 20 | public sealed class GameControlsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Game Controls Usage Page. 24 | // 25 | public static readonly GameControlsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private GameControlsUsagePage() : base(0x0005, "Game Controls") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "3D Game Controller", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Pinball Device", UsageTypes.CA); 42 | case 0x0003: return new Usage(this, id, "Gun Device", UsageTypes.CA); 43 | case 0x0020: return new Usage(this, id, "Point of View", UsageTypes.CP); 44 | case 0x0021: return new Usage(this, id, "Turn Right/Left", UsageTypes.DV); 45 | case 0x0022: return new Usage(this, id, "Pitch Forward/Backward", UsageTypes.DV); 46 | case 0x0023: return new Usage(this, id, "Roll Right/Left", UsageTypes.DV); 47 | case 0x0024: return new Usage(this, id, "Move Right/Left", UsageTypes.DV); 48 | case 0x0025: return new Usage(this, id, "Move Forward/Backward", UsageTypes.DV); 49 | case 0x0026: return new Usage(this, id, "Move Up/Down", UsageTypes.DV); 50 | case 0x0027: return new Usage(this, id, "Lean Right/Left", UsageTypes.DV); 51 | case 0x0028: return new Usage(this, id, "Lean Forward/Backward", UsageTypes.DV); 52 | case 0x0029: return new Usage(this, id, "Height of POV", UsageTypes.DV); 53 | case 0x002a: return new Usage(this, id, "Flipper", UsageTypes.MC); 54 | case 0x002b: return new Usage(this, id, "Secondary Flipper", UsageTypes.MC); 55 | case 0x002c: return new Usage(this, id, "Bump", UsageTypes.MC); 56 | case 0x002d: return new Usage(this, id, "New Game", UsageTypes.OSC); 57 | case 0x002e: return new Usage(this, id, "Shoot Ball", UsageTypes.OSC); 58 | case 0x002f: return new Usage(this, id, "Player", UsageTypes.OSC); 59 | case 0x0030: return new Usage(this, id, "Gun Bolt", UsageTypes.OOC); 60 | case 0x0031: return new Usage(this, id, "Gun Clip", UsageTypes.OOC); 61 | case 0x0032: return new Usage(this, id, "Gun Selector", UsageTypes.NAry); 62 | case 0x0033: return new Usage(this, id, "Gun Single Shot", UsageTypes.Sel); 63 | case 0x0034: return new Usage(this, id, "Gun Burst", UsageTypes.Sel); 64 | case 0x0035: return new Usage(this, id, "Gun Automatic", UsageTypes.Sel); 65 | case 0x0036: return new Usage(this, id, "Gun Safety", UsageTypes.OOC); 66 | case 0x0037: return new Usage(this, id, "Gamepad Fire/Jump", UsageTypes.CL); 67 | case 0x0039: return new Usage(this, id, "Gamepad Trigger", UsageTypes.CL); 68 | case 0x003a: return new Usage(this, id, "Form-fitting Gamepad", UsageTypes.SF); 69 | } 70 | 71 | return base.CreateUsage(id); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/GenericDeviceControlsPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Generic Device Controls Usage Page. 17 | // 18 | [Description("Generic Device Controls Usage Page")] 19 | public enum GenericDeviceControlsPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00060000, 26 | 27 | // 28 | // Background/Nonuser Controls Usage. 29 | // 30 | [Description("Background/Nonuser Controls")] 31 | BackgroundNonuserControls = 0x00060001, 32 | 33 | // 34 | // Battery Strength Usage. 35 | // 36 | [Description("Battery Strength")] 37 | BatteryStrength = 0x00060020, 38 | 39 | // 40 | // Wireless Channel Usage. 41 | // 42 | [Description("Wireless Channel")] 43 | WirelessChannel = 0x00060021, 44 | 45 | // 46 | // Wireless ID Usage. 47 | // 48 | [Description("Wireless ID")] 49 | WirelessID = 0x00060022, 50 | 51 | // 52 | // Discover Wireless Control Usage. 53 | // 54 | [Description("Discover Wireless Control")] 55 | DiscoverWirelessControl = 0x00060023, 56 | 57 | // 58 | // Security Code Character Entered Usage. 59 | // 60 | [Description("Security Code Character Entered")] 61 | SecurityCodeCharacterEntered = 0x00060024, 62 | 63 | // 64 | // Security Code Character Erased Usage. 65 | // 66 | [Description("Security Code Character Erased")] 67 | SecurityCodeCharacterErased = 0x00060025, 68 | 69 | // 70 | // Security Code Cleared Usage. 71 | // 72 | [Description("Security Code Cleared")] 73 | SecurityCodeCleared = 0x00060026, 74 | 75 | // 76 | // Sequence ID Usage. 77 | // 78 | [Description("Sequence ID")] 79 | SequenceID = 0x00060027, 80 | 81 | // 82 | // Sequence ID Reset Usage. 83 | // 84 | [Description("Sequence ID Reset")] 85 | SequenceIDReset = 0x00060028, 86 | 87 | // 88 | // RF Signal Strength Usage. 89 | // 90 | [Description("RF Signal Strength")] 91 | RFSignalStrength = 0x00060029, 92 | 93 | // 94 | // Software Version Usage. 95 | // 96 | [Description("Software Version")] 97 | SoftwareVersion = 0x0006002a, 98 | 99 | // 100 | // Protocol Version Usage. 101 | // 102 | [Description("Protocol Version")] 103 | ProtocolVersion = 0x0006002b, 104 | 105 | // 106 | // Hardware Version Usage. 107 | // 108 | [Description("Hardware Version")] 109 | HardwareVersion = 0x0006002c, 110 | 111 | // 112 | // Major Usage. 113 | // 114 | [Description("Major")] 115 | Major = 0x0006002d, 116 | 117 | // 118 | // Minor Usage. 119 | // 120 | [Description("Minor")] 121 | Minor = 0x0006002e, 122 | 123 | // 124 | // Revision Usage. 125 | // 126 | [Description("Revision")] 127 | Revision = 0x0006002f, 128 | 129 | // 130 | // Handedness Usage. 131 | // 132 | [Description("Handedness")] 133 | Handedness = 0x00060030, 134 | 135 | // 136 | // Either Hand Usage. 137 | // 138 | [Description("Either Hand")] 139 | EitherHand = 0x00060031, 140 | 141 | // 142 | // Left Hand Usage. 143 | // 144 | [Description("Left Hand")] 145 | LeftHand = 0x00060032, 146 | 147 | // 148 | // Right Hand Usage. 149 | // 150 | [Description("Right Hand")] 151 | RightHand = 0x00060033, 152 | 153 | // 154 | // Both Hands Usage. 155 | // 156 | [Description("Both Hands")] 157 | BothHands = 0x00060034, 158 | 159 | // 160 | // Grip Pose Offset Usage. 161 | // 162 | [Description("Grip Pose Offset")] 163 | GripPoseOffset = 0x00060040, 164 | 165 | // 166 | // Pointer Pose Offset Usage. 167 | // 168 | [Description("Pointer Pose Offset")] 169 | PointerPoseOffset = 0x00060041 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/GenericDeviceControlsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Generic Device Controls Usage Page. 19 | // 20 | public sealed class GenericDeviceControlsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Generic Device Controls Usage Page. 24 | // 25 | public static readonly GenericDeviceControlsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private GenericDeviceControlsUsagePage() : base(0x0006, "Generic Device Controls") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Background/Nonuser Controls", UsageTypes.CA); 41 | case 0x0020: return new Usage(this, id, "Battery Strength", UsageTypes.DV); 42 | case 0x0021: return new Usage(this, id, "Wireless Channel", UsageTypes.DV); 43 | case 0x0022: return new Usage(this, id, "Wireless ID", UsageTypes.DV); 44 | case 0x0023: return new Usage(this, id, "Discover Wireless Control", UsageTypes.OSC); 45 | case 0x0024: return new Usage(this, id, "Security Code Character Entered", UsageTypes.OSC); 46 | case 0x0025: return new Usage(this, id, "Security Code Character Erased", UsageTypes.OSC); 47 | case 0x0026: return new Usage(this, id, "Security Code Cleared", UsageTypes.OSC); 48 | case 0x0027: return new Usage(this, id, "Sequence ID", UsageTypes.DV); 49 | case 0x0028: return new Usage(this, id, "Sequence ID Reset", UsageTypes.DF); 50 | case 0x0029: return new Usage(this, id, "RF Signal Strength", UsageTypes.DV); 51 | case 0x002a: return new Usage(this, id, "Software Version", UsageTypes.CL); 52 | case 0x002b: return new Usage(this, id, "Protocol Version", UsageTypes.CL); 53 | case 0x002c: return new Usage(this, id, "Hardware Version", UsageTypes.CL); 54 | case 0x002d: return new Usage(this, id, "Major", UsageTypes.SV); 55 | case 0x002e: return new Usage(this, id, "Minor", UsageTypes.SV); 56 | case 0x002f: return new Usage(this, id, "Revision", UsageTypes.SV); 57 | case 0x0030: return new Usage(this, id, "Handedness", UsageTypes.NAry); 58 | case 0x0031: return new Usage(this, id, "Either Hand", UsageTypes.Sel); 59 | case 0x0032: return new Usage(this, id, "Left Hand", UsageTypes.Sel); 60 | case 0x0033: return new Usage(this, id, "Right Hand", UsageTypes.Sel); 61 | case 0x0034: return new Usage(this, id, "Both Hands", UsageTypes.Sel); 62 | case 0x0040: return new Usage(this, id, "Grip Pose Offset", UsageTypes.CP); 63 | case 0x0041: return new Usage(this, id, "Pointer Pose Offset", UsageTypes.CP); 64 | } 65 | 66 | return base.CreateUsage(id); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/HapticsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Haptics Usage Page. 19 | // 20 | public sealed class HapticsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Haptics Usage Page. 24 | // 25 | public static readonly HapticsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private HapticsUsagePage() : base(0x000e, "Haptics") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Simple Haptic Controller", UsageTypes.CA|UsageTypes.CL); 41 | case 0x0010: return new Usage(this, id, "Waveform List", UsageTypes.NAry); 42 | case 0x0011: return new Usage(this, id, "Duration List", UsageTypes.NAry); 43 | case 0x0020: return new Usage(this, id, "Auto Trigger", UsageTypes.DV); 44 | case 0x0021: return new Usage(this, id, "Manual Trigger", UsageTypes.DV); 45 | case 0x0022: return new Usage(this, id, "Auto Trigger Associated Control", UsageTypes.SV); 46 | case 0x0023: return new Usage(this, id, "Intensity", UsageTypes.DV); 47 | case 0x0024: return new Usage(this, id, "Repeat Count", UsageTypes.DV); 48 | case 0x0025: return new Usage(this, id, "Retrigger Period", UsageTypes.DV); 49 | case 0x0026: return new Usage(this, id, "Waveform Vendor Page", UsageTypes.SV); 50 | case 0x0027: return new Usage(this, id, "Waveform Vendor ID", UsageTypes.SV); 51 | case 0x0028: return new Usage(this, id, "Waveform Cutoff Time", UsageTypes.SV); 52 | case 0x1001: return new Usage(this, id, "Waveform None", UsageTypes.SV); 53 | case 0x1002: return new Usage(this, id, "Waveform Stop", UsageTypes.SV); 54 | case 0x1003: return new Usage(this, id, "Waveform Click", UsageTypes.SV); 55 | case 0x1004: return new Usage(this, id, "Waveform Buzz Continuous", UsageTypes.SV); 56 | case 0x1005: return new Usage(this, id, "Waveform Rumble Continuous", UsageTypes.SV); 57 | case 0x1006: return new Usage(this, id, "Waveform Press", UsageTypes.SV); 58 | case 0x1007: return new Usage(this, id, "Waveform Release", UsageTypes.SV); 59 | case 0x1008: return new Usage(this, id, "Waveform Hover", UsageTypes.SV); 60 | case 0x1009: return new Usage(this, id, "Waveform Success", UsageTypes.SV); 61 | case 0x100a: return new Usage(this, id, "Waveform Error", UsageTypes.SV); 62 | case 0x100b: return new Usage(this, id, "Waveform Ink Continuous", UsageTypes.SV); 63 | case 0x100c: return new Usage(this, id, "Waveform Pencil Continuous", UsageTypes.SV); 64 | case 0x100d: return new Usage(this, id, "Waveform Marker Continuous", UsageTypes.SV); 65 | case 0x100e: return new Usage(this, id, "Waveform Chisel Marker Continuous", UsageTypes.SV); 66 | case 0x100f: return new Usage(this, id, "Waveform Brush Continuous", UsageTypes.SV); 67 | case 0x1010: return new Usage(this, id, "Waveform Eraser Continuous", UsageTypes.SV); 68 | case 0x1011: return new Usage(this, id, "Waveform Sparkle Continuous", UsageTypes.SV); 69 | } 70 | 71 | return base.CreateUsage(id); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/LightingAndIlluminationUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Lighting And Illumination Usage Page. 19 | // 20 | public sealed class LightingAndIlluminationUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Lighting And Illumination Usage Page. 24 | // 25 | public static readonly LightingAndIlluminationUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private LightingAndIlluminationUsagePage() : base(0x0059, "Lighting And Illumination") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "LampArray", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "LampArrayAttributesReport", UsageTypes.CL); 42 | case 0x0003: return new Usage(this, id, "LampCount", UsageTypes.SV|UsageTypes.DV); 43 | case 0x0004: return new Usage(this, id, "BoundingBoxWidthInMicrometers", UsageTypes.SV); 44 | case 0x0005: return new Usage(this, id, "BoundingBoxHeightInMicrometers", UsageTypes.SV); 45 | case 0x0006: return new Usage(this, id, "BoundingBoxDepthInMicrometers", UsageTypes.SV); 46 | case 0x0007: return new Usage(this, id, "LampArrayKind", UsageTypes.SV); 47 | case 0x0008: return new Usage(this, id, "MinUpdateIntervalInMicroseconds", UsageTypes.SV); 48 | case 0x0020: return new Usage(this, id, "LampAttributesRequestReport", UsageTypes.CL); 49 | case 0x0021: return new Usage(this, id, "LampId", UsageTypes.SV|UsageTypes.DV); 50 | case 0x0022: return new Usage(this, id, "LampAttributesResponseReport", UsageTypes.CL); 51 | case 0x0023: return new Usage(this, id, "PositionXInMicrometers", UsageTypes.DV); 52 | case 0x0024: return new Usage(this, id, "PositionYInMicrometers", UsageTypes.DV); 53 | case 0x0025: return new Usage(this, id, "PositionZInMicrometers", UsageTypes.DV); 54 | case 0x0026: return new Usage(this, id, "LampPurposes", UsageTypes.DV); 55 | case 0x0027: return new Usage(this, id, "UpdateLatencyInMicroseconds", UsageTypes.DV); 56 | case 0x0028: return new Usage(this, id, "RedLevelCount", UsageTypes.DV); 57 | case 0x0029: return new Usage(this, id, "GreenLevelCount", UsageTypes.DV); 58 | case 0x002a: return new Usage(this, id, "BlueLevelCount", UsageTypes.DV); 59 | case 0x002b: return new Usage(this, id, "IntensityLevelCount", UsageTypes.DV); 60 | case 0x002c: return new Usage(this, id, "IsProgrammable", UsageTypes.DV); 61 | case 0x002d: return new Usage(this, id, "InputBinding", UsageTypes.DV); 62 | case 0x0050: return new Usage(this, id, "LampMultiUpdateReport", UsageTypes.CL); 63 | case 0x0051: return new Usage(this, id, "RedUpdateChannel", UsageTypes.DV); 64 | case 0x0052: return new Usage(this, id, "GreenUpdateChannel", UsageTypes.DV); 65 | case 0x0053: return new Usage(this, id, "BlueUpdateChannel", UsageTypes.DV); 66 | case 0x0054: return new Usage(this, id, "IntensityUpdateChannel", UsageTypes.DV); 67 | case 0x0055: return new Usage(this, id, "LampUpdateFlags", UsageTypes.DV); 68 | case 0x0060: return new Usage(this, id, "LampRangeUpdateReport", UsageTypes.CL); 69 | case 0x0061: return new Usage(this, id, "LampIdStart", UsageTypes.DV); 70 | case 0x0062: return new Usage(this, id, "LampIdEnd", UsageTypes.DV); 71 | case 0x0070: return new Usage(this, id, "LampArrayControlReport", UsageTypes.CL); 72 | case 0x0071: return new Usage(this, id, "AutonomousMode", UsageTypes.DV); 73 | } 74 | 75 | return base.CreateUsage(id); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MagneticStripeReaderPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Magnetic Stripe Reader Usage Page. 17 | // 18 | [Description("Magnetic Stripe Reader Usage Page")] 19 | public enum MagneticStripeReaderPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x008e0000, 26 | 27 | // 28 | // MSR Device Read-Only Usage. 29 | // 30 | [Description("MSR Device Read-Only")] 31 | MSRDeviceReadOnly = 0x008e0001, 32 | 33 | // 34 | // Track 1 Length Usage. 35 | // 36 | [Description("Track 1 Length")] 37 | Track1Length = 0x008e0011, 38 | 39 | // 40 | // Track 2 Length Usage. 41 | // 42 | [Description("Track 2 Length")] 43 | Track2Length = 0x008e0012, 44 | 45 | // 46 | // Track 3 Length Usage. 47 | // 48 | [Description("Track 3 Length")] 49 | Track3Length = 0x008e0013, 50 | 51 | // 52 | // Track JIS Length Usage. 53 | // 54 | [Description("Track JIS Length")] 55 | TrackJISLength = 0x008e0014, 56 | 57 | // 58 | // Track Data Usage. 59 | // 60 | [Description("Track Data")] 61 | TrackData = 0x008e0020, 62 | 63 | // 64 | // Track 1 Data Usage. 65 | // 66 | [Description("Track 1 Data")] 67 | Track1Data = 0x008e0021, 68 | 69 | // 70 | // Track 2 Data Usage. 71 | // 72 | [Description("Track 2 Data")] 73 | Track2Data = 0x008e0022, 74 | 75 | // 76 | // Track 3 Data Usage. 77 | // 78 | [Description("Track 3 Data")] 79 | Track3Data = 0x008e0023, 80 | 81 | // 82 | // Track JIS Data Usage. 83 | // 84 | [Description("Track JIS Data")] 85 | TrackJISData = 0x008e0024 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MagneticStripeReaderUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Magnetic Stripe Reader Usage Page. 19 | // 20 | public sealed class MagneticStripeReaderUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Magnetic Stripe Reader Usage Page. 24 | // 25 | public static readonly MagneticStripeReaderUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private MagneticStripeReaderUsagePage() : base(0x008e, "Magnetic Stripe Reader") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "MSR Device Read-Only", UsageTypes.CA); 41 | case 0x0011: return new Usage(this, id, "Track 1 Length", UsageTypes.DV); 42 | case 0x0012: return new Usage(this, id, "Track 2 Length", UsageTypes.DV); 43 | case 0x0013: return new Usage(this, id, "Track 3 Length", UsageTypes.DV); 44 | case 0x0014: return new Usage(this, id, "Track JIS Length", UsageTypes.DV); 45 | case 0x0020: return new Usage(this, id, "Track Data", UsageTypes.SF|UsageTypes.DF|UsageTypes.DV); 46 | case 0x0021: return new Usage(this, id, "Track 1 Data", UsageTypes.SF|UsageTypes.DF|UsageTypes.DV); 47 | case 0x0022: return new Usage(this, id, "Track 2 Data", UsageTypes.SF|UsageTypes.DF|UsageTypes.DV); 48 | case 0x0023: return new Usage(this, id, "Track 3 Data", UsageTypes.SF|UsageTypes.DF|UsageTypes.DV); 49 | case 0x0024: return new Usage(this, id, "Track JIS Data", UsageTypes.SF|UsageTypes.DF|UsageTypes.DV); 50 | } 51 | 52 | return base.CreateUsage(id); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MedicalInstrumentUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Medical Instrument Usage Page. 19 | // 20 | public sealed class MedicalInstrumentUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Medical Instrument Usage Page. 24 | // 25 | public static readonly MedicalInstrumentUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private MedicalInstrumentUsagePage() : base(0x0040, "Medical Instrument") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Medical Ultrasound", UsageTypes.CA); 41 | case 0x0020: return new Usage(this, id, "VCR/Acquisition", UsageTypes.OOC); 42 | case 0x0021: return new Usage(this, id, "Freeze/Thaw", UsageTypes.OOC); 43 | case 0x0022: return new Usage(this, id, "Clip Store", UsageTypes.OSC); 44 | case 0x0023: return new Usage(this, id, "Update", UsageTypes.OSC); 45 | case 0x0024: return new Usage(this, id, "Next", UsageTypes.OSC); 46 | case 0x0025: return new Usage(this, id, "Save", UsageTypes.OSC); 47 | case 0x0026: return new Usage(this, id, "Print", UsageTypes.OSC); 48 | case 0x0027: return new Usage(this, id, "Microphone Enable", UsageTypes.OSC); 49 | case 0x0040: return new Usage(this, id, "Cine", UsageTypes.LC); 50 | case 0x0041: return new Usage(this, id, "Transmit Power", UsageTypes.LC); 51 | case 0x0042: return new Usage(this, id, "Volume", UsageTypes.LC); 52 | case 0x0043: return new Usage(this, id, "Focus", UsageTypes.LC); 53 | case 0x0044: return new Usage(this, id, "Depth", UsageTypes.LC); 54 | case 0x0060: return new Usage(this, id, "Soft Step - Primary", UsageTypes.LC); 55 | case 0x0061: return new Usage(this, id, "Soft Step - Secondary", UsageTypes.LC); 56 | case 0x0070: return new Usage(this, id, "Depth Gain Compensation", UsageTypes.LC); 57 | case 0x0080: return new Usage(this, id, "Zoom Select", UsageTypes.OSC); 58 | case 0x0081: return new Usage(this, id, "Zoom Adjust", UsageTypes.LC); 59 | case 0x0082: return new Usage(this, id, "Spectral Doppler Mode Select", UsageTypes.OSC); 60 | case 0x0083: return new Usage(this, id, "Spectral Doppler Adjust", UsageTypes.LC); 61 | case 0x0084: return new Usage(this, id, "Color Doppler Mode Select", UsageTypes.OSC); 62 | case 0x0085: return new Usage(this, id, "Color Doppler Adjust", UsageTypes.LC); 63 | case 0x0086: return new Usage(this, id, "Motion Mode Select", UsageTypes.OSC); 64 | case 0x0087: return new Usage(this, id, "Motion Mode Adjust", UsageTypes.LC); 65 | case 0x0088: return new Usage(this, id, "2-D Mode Select", UsageTypes.OSC); 66 | case 0x0089: return new Usage(this, id, "2-D Mode Adjust", UsageTypes.LC); 67 | case 0x00a0: return new Usage(this, id, "Soft Control Select", UsageTypes.OSC); 68 | case 0x00a1: return new Usage(this, id, "Soft Control Adjust", UsageTypes.LC); 69 | } 70 | 71 | return base.CreateUsage(id); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MonitorEnumeratedPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Monitor Enumerated Usage Page. 17 | // 18 | [Description("Monitor Enumerated Usage Page")] 19 | public enum MonitorEnumeratedPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00810000, 26 | 27 | // Range: 0x0001 -> 0xffff 28 | 29 | // 30 | // Enum 0 Usage. 31 | // 32 | [Description("Enum 0")] 33 | Enum0 = 0x00810001, 34 | 35 | // 36 | // Enum 1 Usage. 37 | // 38 | [Description("Enum 1")] 39 | Enum1 = 0x00810002, 40 | 41 | // 42 | // Enum 2 Usage. 43 | // 44 | [Description("Enum 2")] 45 | Enum2 = 0x00810003, 46 | 47 | // 48 | // Enum 3 Usage. 49 | // 50 | [Description("Enum 3")] 51 | Enum3 = 0x00810004, 52 | 53 | // 54 | // Enum 4 Usage. 55 | // 56 | [Description("Enum 4")] 57 | Enum4 = 0x00810005, 58 | 59 | // 60 | // Enum 5 Usage. 61 | // 62 | [Description("Enum 5")] 63 | Enum5 = 0x00810006, 64 | 65 | // 66 | // Enum 6 Usage. 67 | // 68 | [Description("Enum 6")] 69 | Enum6 = 0x00810007, 70 | 71 | // 72 | // Enum 7 Usage. 73 | // 74 | [Description("Enum 7")] 75 | Enum7 = 0x00810008, 76 | 77 | // 78 | // Enum 8 Usage. 79 | // 80 | [Description("Enum 8")] 81 | Enum8 = 0x00810009, 82 | 83 | // 84 | // Enum 9 Usage. 85 | // 86 | [Description("Enum 9")] 87 | Enum9 = 0x0081000a, 88 | 89 | // 90 | // Enum 10 Usage. 91 | // 92 | [Description("Enum 10")] 93 | Enum10 = 0x0081000b, 94 | 95 | // 96 | // Enum 11 Usage. 97 | // 98 | [Description("Enum 11")] 99 | Enum11 = 0x0081000c, 100 | 101 | // 102 | // Enum 12 Usage. 103 | // 104 | [Description("Enum 12")] 105 | Enum12 = 0x0081000d, 106 | 107 | // 108 | // Enum 13 Usage. 109 | // 110 | [Description("Enum 13")] 111 | Enum13 = 0x0081000e, 112 | 113 | // 114 | // Enum 14 Usage. 115 | // 116 | [Description("Enum 14")] 117 | Enum14 = 0x0081000f, 118 | 119 | // 120 | // Enum 15 Usage. 121 | // 122 | [Description("Enum 15")] 123 | Enum15 = 0x00810010 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MonitorEnumeratedUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Monitor Enumerated Usage Page. 19 | // 20 | public sealed class MonitorEnumeratedUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Monitor Enumerated Usage Page. 24 | // 25 | public static readonly MonitorEnumeratedUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private MonitorEnumeratedUsagePage() : base(0x0081, "Monitor Enumerated") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Enum 0", UsageTypes.Sel); 41 | case 0x0002: return new Usage(this, id, "Enum 1", UsageTypes.Sel); 42 | case 0x0003: return new Usage(this, id, "Enum 2", UsageTypes.Sel); 43 | case 0x0004: return new Usage(this, id, "Enum 3", UsageTypes.Sel); 44 | case 0x0005: return new Usage(this, id, "Enum 4", UsageTypes.Sel); 45 | case 0x0006: return new Usage(this, id, "Enum 5", UsageTypes.Sel); 46 | case 0x0007: return new Usage(this, id, "Enum 6", UsageTypes.Sel); 47 | case 0x0008: return new Usage(this, id, "Enum 7", UsageTypes.Sel); 48 | case 0x0009: return new Usage(this, id, "Enum 8", UsageTypes.Sel); 49 | case 0x000a: return new Usage(this, id, "Enum 9", UsageTypes.Sel); 50 | case 0x000b: return new Usage(this, id, "Enum 10", UsageTypes.Sel); 51 | case 0x000c: return new Usage(this, id, "Enum 11", UsageTypes.Sel); 52 | case 0x000d: return new Usage(this, id, "Enum 12", UsageTypes.Sel); 53 | case 0x000e: return new Usage(this, id, "Enum 13", UsageTypes.Sel); 54 | case 0x000f: return new Usage(this, id, "Enum 14", UsageTypes.Sel); 55 | case 0x0010: return new Usage(this, id, "Enum 15", UsageTypes.Sel); 56 | } 57 | var n = (ushort)(id-0x0001); 58 | if (id >= 0x0011 || id <= 0xffff) return new Usage(this, id, $"Enum {n}", UsageTypes.Sel); 59 | 60 | return base.CreateUsage(id); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MonitorPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Monitor Usage Page. 17 | // 18 | [Description("Monitor Usage Page")] 19 | public enum MonitorPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00800000, 26 | 27 | // 28 | // Monitor Control Usage. 29 | // 30 | [Description("Monitor Control")] 31 | MonitorControl = 0x00800001, 32 | 33 | // 34 | // EDID Information Usage. 35 | // 36 | [Description("EDID Information")] 37 | EDIDInformation = 0x00800002, 38 | 39 | // 40 | // VDIF Information Usage. 41 | // 42 | [Description("VDIF Information")] 43 | VDIFInformation = 0x00800003, 44 | 45 | // 46 | // VESA Version Usage. 47 | // 48 | [Description("VESA Version")] 49 | VESAVersion = 0x00800004 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/MonitorUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Monitor Usage Page. 19 | // 20 | public sealed class MonitorUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Monitor Usage Page. 24 | // 25 | public static readonly MonitorUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private MonitorUsagePage() : base(0x0080, "Monitor") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Monitor Control", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "EDID Information", UsageTypes.SV); 42 | case 0x0003: return new Usage(this, id, "VDIF Information", UsageTypes.SV); 43 | case 0x0004: return new Usage(this, id, "VESA Version", UsageTypes.SV); 44 | } 45 | 46 | return base.CreateUsage(id); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/OrdinalPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // Ordinal Usage Page. 17 | // 18 | [Description("Ordinal Usage Page")] 19 | public enum OrdinalPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x000a0000, 26 | 27 | // Range: 0x0001 -> 0xffff 28 | 29 | // 30 | // Instance 0 Usage. 31 | // 32 | [Description("Instance 0")] 33 | Instance0 = 0x000a0001, 34 | 35 | // 36 | // Instance 1 Usage. 37 | // 38 | [Description("Instance 1")] 39 | Instance1 = 0x000a0002, 40 | 41 | // 42 | // Instance 2 Usage. 43 | // 44 | [Description("Instance 2")] 45 | Instance2 = 0x000a0003, 46 | 47 | // 48 | // Instance 3 Usage. 49 | // 50 | [Description("Instance 3")] 51 | Instance3 = 0x000a0004, 52 | 53 | // 54 | // Instance 4 Usage. 55 | // 56 | [Description("Instance 4")] 57 | Instance4 = 0x000a0005, 58 | 59 | // 60 | // Instance 5 Usage. 61 | // 62 | [Description("Instance 5")] 63 | Instance5 = 0x000a0006, 64 | 65 | // 66 | // Instance 6 Usage. 67 | // 68 | [Description("Instance 6")] 69 | Instance6 = 0x000a0007, 70 | 71 | // 72 | // Instance 7 Usage. 73 | // 74 | [Description("Instance 7")] 75 | Instance7 = 0x000a0008, 76 | 77 | // 78 | // Instance 8 Usage. 79 | // 80 | [Description("Instance 8")] 81 | Instance8 = 0x000a0009, 82 | 83 | // 84 | // Instance 9 Usage. 85 | // 86 | [Description("Instance 9")] 87 | Instance9 = 0x000a000a, 88 | 89 | // 90 | // Instance 10 Usage. 91 | // 92 | [Description("Instance 10")] 93 | Instance10 = 0x000a000b, 94 | 95 | // 96 | // Instance 11 Usage. 97 | // 98 | [Description("Instance 11")] 99 | Instance11 = 0x000a000c, 100 | 101 | // 102 | // Instance 12 Usage. 103 | // 104 | [Description("Instance 12")] 105 | Instance12 = 0x000a000d, 106 | 107 | // 108 | // Instance 13 Usage. 109 | // 110 | [Description("Instance 13")] 111 | Instance13 = 0x000a000e, 112 | 113 | // 114 | // Instance 14 Usage. 115 | // 116 | [Description("Instance 14")] 117 | Instance14 = 0x000a000f, 118 | 119 | // 120 | // Instance 15 Usage. 121 | // 122 | [Description("Instance 15")] 123 | Instance15 = 0x000a0010 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/OrdinalUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Ordinal Usage Page. 19 | // 20 | public sealed class OrdinalUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Ordinal Usage Page. 24 | // 25 | public static readonly OrdinalUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private OrdinalUsagePage() : base(0x000a, "Ordinal") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Instance 0", UsageTypes.UM); 41 | case 0x0002: return new Usage(this, id, "Instance 1", UsageTypes.UM); 42 | case 0x0003: return new Usage(this, id, "Instance 2", UsageTypes.UM); 43 | case 0x0004: return new Usage(this, id, "Instance 3", UsageTypes.UM); 44 | case 0x0005: return new Usage(this, id, "Instance 4", UsageTypes.UM); 45 | case 0x0006: return new Usage(this, id, "Instance 5", UsageTypes.UM); 46 | case 0x0007: return new Usage(this, id, "Instance 6", UsageTypes.UM); 47 | case 0x0008: return new Usage(this, id, "Instance 7", UsageTypes.UM); 48 | case 0x0009: return new Usage(this, id, "Instance 8", UsageTypes.UM); 49 | case 0x000a: return new Usage(this, id, "Instance 9", UsageTypes.UM); 50 | case 0x000b: return new Usage(this, id, "Instance 10", UsageTypes.UM); 51 | case 0x000c: return new Usage(this, id, "Instance 11", UsageTypes.UM); 52 | case 0x000d: return new Usage(this, id, "Instance 12", UsageTypes.UM); 53 | case 0x000e: return new Usage(this, id, "Instance 13", UsageTypes.UM); 54 | case 0x000f: return new Usage(this, id, "Instance 14", UsageTypes.UM); 55 | case 0x0010: return new Usage(this, id, "Instance 15", UsageTypes.UM); 56 | } 57 | var n = (ushort)(id-0x0001); 58 | if (id >= 0x0011 || id <= 0xffff) return new Usage(this, id, $"Instance {n}", UsageTypes.UM); 59 | 60 | return base.CreateUsage(id); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/ScalesUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Scales Usage Page. 19 | // 20 | public sealed class ScalesUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Scales Usage Page. 24 | // 25 | public static readonly ScalesUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private ScalesUsagePage() : base(0x008d, "Scales") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Scales", UsageTypes.CA); 41 | case 0x0020: return new Usage(this, id, "Scale Device", UsageTypes.CL); 42 | case 0x0021: return new Usage(this, id, "Scale Class", UsageTypes.NAry); 43 | case 0x0022: return new Usage(this, id, "Scale Class I Metric", UsageTypes.Sel); 44 | case 0x0023: return new Usage(this, id, "Scale Class II Metric", UsageTypes.Sel); 45 | case 0x0024: return new Usage(this, id, "Scale Class III Metric", UsageTypes.Sel); 46 | case 0x0025: return new Usage(this, id, "Scale Class IIIL Metric", UsageTypes.Sel); 47 | case 0x0026: return new Usage(this, id, "Scale Class IV Metric", UsageTypes.Sel); 48 | case 0x0027: return new Usage(this, id, "Scale Class III English", UsageTypes.Sel); 49 | case 0x0028: return new Usage(this, id, "Scale Class IIIL English", UsageTypes.Sel); 50 | case 0x0029: return new Usage(this, id, "Scale Class IV English", UsageTypes.Sel); 51 | case 0x002a: return new Usage(this, id, "Scale Class Generic", UsageTypes.Sel); 52 | case 0x0030: return new Usage(this, id, "Scale Attribute Report", UsageTypes.CL); 53 | case 0x0031: return new Usage(this, id, "Scale Control Report", UsageTypes.CL); 54 | case 0x0032: return new Usage(this, id, "Scale Data Report", UsageTypes.CL); 55 | case 0x0033: return new Usage(this, id, "Scale Status Report", UsageTypes.CL); 56 | case 0x0034: return new Usage(this, id, "Scale Weight Limit Report", UsageTypes.CL); 57 | case 0x0035: return new Usage(this, id, "Scale Statistics Report", UsageTypes.CL); 58 | case 0x0040: return new Usage(this, id, "Data Weight", UsageTypes.DV); 59 | case 0x0041: return new Usage(this, id, "Data Scaling", UsageTypes.DV); 60 | case 0x0050: return new Usage(this, id, "Weight Unit", UsageTypes.CL); 61 | case 0x0051: return new Usage(this, id, "Weight Unit Milligram", UsageTypes.Sel); 62 | case 0x0052: return new Usage(this, id, "Weight Unit Gram", UsageTypes.Sel); 63 | case 0x0053: return new Usage(this, id, "Weight Unit Kilogram", UsageTypes.Sel); 64 | case 0x0054: return new Usage(this, id, "Weight Unit Carats", UsageTypes.Sel); 65 | case 0x0055: return new Usage(this, id, "Weight Unit Taels", UsageTypes.Sel); 66 | case 0x0056: return new Usage(this, id, "Weight Unit Grains", UsageTypes.Sel); 67 | case 0x0057: return new Usage(this, id, "Weight Unit Pennyweights", UsageTypes.Sel); 68 | case 0x0058: return new Usage(this, id, "Weight Unit Metric Ton", UsageTypes.Sel); 69 | case 0x0059: return new Usage(this, id, "Weight Unit Avoir Ton", UsageTypes.Sel); 70 | case 0x005a: return new Usage(this, id, "Weight Unit Troy Ounce", UsageTypes.Sel); 71 | case 0x005b: return new Usage(this, id, "Weight Unit Ounce", UsageTypes.Sel); 72 | case 0x005c: return new Usage(this, id, "Weight Unit Pound", UsageTypes.Sel); 73 | case 0x0060: return new Usage(this, id, "Calibration Count", UsageTypes.DV); 74 | case 0x0061: return new Usage(this, id, "Re-Zero Count", UsageTypes.DV); 75 | case 0x0070: return new Usage(this, id, "Scale Status", UsageTypes.NAry); 76 | case 0x0071: return new Usage(this, id, "Scale Status Fault", UsageTypes.Sel); 77 | case 0x0072: return new Usage(this, id, "Scale Status Stable at Center of Zero", UsageTypes.Sel); 78 | case 0x0073: return new Usage(this, id, "Scale Status In Motion", UsageTypes.Sel); 79 | case 0x0074: return new Usage(this, id, "Scale Status Weight Stable", UsageTypes.Sel); 80 | case 0x0075: return new Usage(this, id, "Scale Status Under Zero", UsageTypes.Sel); 81 | case 0x0076: return new Usage(this, id, "Scale Status Over Weight Limit", UsageTypes.Sel); 82 | case 0x0077: return new Usage(this, id, "Scale Status Requires Calibration", UsageTypes.Sel); 83 | case 0x0078: return new Usage(this, id, "Scale Status Requires Rezeroing", UsageTypes.Sel); 84 | case 0x0080: return new Usage(this, id, "Zero Scale", UsageTypes.OOC); 85 | case 0x0081: return new Usage(this, id, "Enforced Zero Return", UsageTypes.OOC); 86 | } 87 | 88 | return base.CreateUsage(id); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/SoCPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // SoC Usage Page. 17 | // 18 | [Description("SoC Usage Page")] 19 | public enum SoCPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00110000, 26 | 27 | // 28 | // SocControl Usage. 29 | // 30 | [Description("SocControl")] 31 | SocControl = 0x00110001, 32 | 33 | // 34 | // FirmwareTransfer Usage. 35 | // 36 | [Description("FirmwareTransfer")] 37 | FirmwareTransfer = 0x00110002, 38 | 39 | // 40 | // FirmwareFileId Usage. 41 | // 42 | [Description("FirmwareFileId")] 43 | FirmwareFileId = 0x00110003, 44 | 45 | // 46 | // FileOffsetInBytes Usage. 47 | // 48 | [Description("FileOffsetInBytes")] 49 | FileOffsetInBytes = 0x00110004, 50 | 51 | // 52 | // FileTransferSizeMaxInBytes Usage. 53 | // 54 | [Description("FileTransferSizeMaxInBytes")] 55 | FileTransferSizeMaxInBytes = 0x00110005, 56 | 57 | // 58 | // FilePayload Usage. 59 | // 60 | [Description("FilePayload")] 61 | FilePayload = 0x00110006, 62 | 63 | // 64 | // FilePayloadSizeInBytes Usage. 65 | // 66 | [Description("FilePayloadSizeInBytes")] 67 | FilePayloadSizeInBytes = 0x00110007, 68 | 69 | // 70 | // FilePayloadContainsLastBytes Usage. 71 | // 72 | [Description("FilePayloadContainsLastBytes")] 73 | FilePayloadContainsLastBytes = 0x00110008, 74 | 75 | // 76 | // FileTransferStop Usage. 77 | // 78 | [Description("FileTransferStop")] 79 | FileTransferStop = 0x00110009, 80 | 81 | // 82 | // FileTransferTillEnd Usage. 83 | // 84 | [Description("FileTransferTillEnd")] 85 | FileTransferTillEnd = 0x0011000a 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/SoCUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // SoC Usage Page. 19 | // 20 | public sealed class SoCUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of SoC Usage Page. 24 | // 25 | public static readonly SoCUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private SoCUsagePage() : base(0x0011, "SoC") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "SocControl", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "FirmwareTransfer", UsageTypes.CL); 42 | case 0x0003: return new Usage(this, id, "FirmwareFileId", UsageTypes.DV); 43 | case 0x0004: return new Usage(this, id, "FileOffsetInBytes", UsageTypes.DV); 44 | case 0x0005: return new Usage(this, id, "FileTransferSizeMaxInBytes", UsageTypes.DV); 45 | case 0x0006: return new Usage(this, id, "FilePayload", UsageTypes.DV); 46 | case 0x0007: return new Usage(this, id, "FilePayloadSizeInBytes", UsageTypes.DV); 47 | case 0x0008: return new Usage(this, id, "FilePayloadContainsLastBytes", UsageTypes.DF); 48 | case 0x0009: return new Usage(this, id, "FileTransferStop", UsageTypes.DF); 49 | case 0x000a: return new Usage(this, id, "FileTransferTillEnd", UsageTypes.DF); 50 | } 51 | 52 | return base.CreateUsage(id); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/SportControlsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // Sport Controls Usage Page. 19 | // 20 | public sealed class SportControlsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of Sport Controls Usage Page. 24 | // 25 | public static readonly SportControlsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private SportControlsUsagePage() : base(0x0004, "Sport Controls") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Baseball Bat", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Golf Club", UsageTypes.CA); 42 | case 0x0003: return new Usage(this, id, "Rowing Machine", UsageTypes.CA); 43 | case 0x0004: return new Usage(this, id, "Treadmill", UsageTypes.CA); 44 | case 0x0030: return new Usage(this, id, "Oar", UsageTypes.DV); 45 | case 0x0031: return new Usage(this, id, "Slope", UsageTypes.DV); 46 | case 0x0032: return new Usage(this, id, "Rate", UsageTypes.DV); 47 | case 0x0033: return new Usage(this, id, "Stick Speed", UsageTypes.DV); 48 | case 0x0034: return new Usage(this, id, "Stick Face Angle", UsageTypes.DV); 49 | case 0x0035: return new Usage(this, id, "Stick Heel/Toe", UsageTypes.DV); 50 | case 0x0036: return new Usage(this, id, "Stick Follow Through", UsageTypes.DV); 51 | case 0x0037: return new Usage(this, id, "Stick Tempo", UsageTypes.DV); 52 | case 0x0038: return new Usage(this, id, "Stick Type", UsageTypes.NAry); 53 | case 0x0039: return new Usage(this, id, "Stick Height", UsageTypes.DV); 54 | case 0x0050: return new Usage(this, id, "Putter", UsageTypes.Sel); 55 | case 0x0051: return new Usage(this, id, "1 Iron", UsageTypes.Sel); 56 | case 0x0052: return new Usage(this, id, "2 Iron", UsageTypes.Sel); 57 | case 0x0053: return new Usage(this, id, "3 Iron", UsageTypes.Sel); 58 | case 0x0054: return new Usage(this, id, "4 Iron", UsageTypes.Sel); 59 | case 0x0055: return new Usage(this, id, "5 Iron", UsageTypes.Sel); 60 | case 0x0056: return new Usage(this, id, "6 Iron", UsageTypes.Sel); 61 | case 0x0057: return new Usage(this, id, "7 Iron", UsageTypes.Sel); 62 | case 0x0058: return new Usage(this, id, "8 Iron", UsageTypes.Sel); 63 | case 0x0059: return new Usage(this, id, "9 Iron", UsageTypes.Sel); 64 | case 0x005a: return new Usage(this, id, "10 Iron", UsageTypes.Sel); 65 | case 0x005b: return new Usage(this, id, "11 Iron", UsageTypes.Sel); 66 | case 0x005c: return new Usage(this, id, "Sand Wedge", UsageTypes.Sel); 67 | case 0x005d: return new Usage(this, id, "Loft Wedge", UsageTypes.Sel); 68 | case 0x005e: return new Usage(this, id, "Power Wedge", UsageTypes.Sel); 69 | case 0x005f: return new Usage(this, id, "1 Wood", UsageTypes.Sel); 70 | case 0x0060: return new Usage(this, id, "3 Wood", UsageTypes.Sel); 71 | case 0x0061: return new Usage(this, id, "5 Wood", UsageTypes.Sel); 72 | case 0x0062: return new Usage(this, id, "7 Wood", UsageTypes.Sel); 73 | case 0x0063: return new Usage(this, id, "9 Wood", UsageTypes.Sel); 74 | } 75 | 76 | return base.CreateUsage(id); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/VESAVirtualControlsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // VESA Virtual Controls Usage Page. 19 | // 20 | public sealed class VESAVirtualControlsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of VESA Virtual Controls Usage Page. 24 | // 25 | public static readonly VESAVirtualControlsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private VESAVirtualControlsUsagePage() : base(0x0082, "VESA Virtual Controls") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Degauss", UsageTypes.DV); 41 | case 0x0010: return new Usage(this, id, "Brightness", UsageTypes.DV); 42 | case 0x0012: return new Usage(this, id, "Contrast", UsageTypes.DV); 43 | case 0x0016: return new Usage(this, id, "Red Video Gain", UsageTypes.DV); 44 | case 0x0018: return new Usage(this, id, "Green Video Gain", UsageTypes.DV); 45 | case 0x001a: return new Usage(this, id, "Blue Video Gain", UsageTypes.DV); 46 | case 0x001c: return new Usage(this, id, "Focus", UsageTypes.DV); 47 | case 0x0020: return new Usage(this, id, "Horizontal Position", UsageTypes.DV); 48 | case 0x0022: return new Usage(this, id, "Horizontal Size", UsageTypes.DV); 49 | case 0x0024: return new Usage(this, id, "Horizontal Pincushion", UsageTypes.DV); 50 | case 0x0026: return new Usage(this, id, "Horizontal Pincushion Balance", UsageTypes.DV); 51 | case 0x0028: return new Usage(this, id, "Horizontal Misconvergence", UsageTypes.DV); 52 | case 0x002a: return new Usage(this, id, "Horizontal Linearity", UsageTypes.DV); 53 | case 0x002c: return new Usage(this, id, "Horizontal Linearity Balance", UsageTypes.DV); 54 | case 0x0030: return new Usage(this, id, "Vertical Position", UsageTypes.DV); 55 | case 0x0032: return new Usage(this, id, "Vertical Size", UsageTypes.DV); 56 | case 0x0034: return new Usage(this, id, "Vertical Pincushion", UsageTypes.DV); 57 | case 0x0036: return new Usage(this, id, "Vertical Pincushion Balance", UsageTypes.DV); 58 | case 0x0038: return new Usage(this, id, "Vertical Misconvergence", UsageTypes.DV); 59 | case 0x003a: return new Usage(this, id, "Vertical Linearity", UsageTypes.DV); 60 | case 0x003c: return new Usage(this, id, "Vertical Linearity Balance", UsageTypes.DV); 61 | case 0x0040: return new Usage(this, id, "Parallelogram Distortion (Key Balance)", UsageTypes.DV); 62 | case 0x0042: return new Usage(this, id, "Trapezoidal Distortion (Key)", UsageTypes.DV); 63 | case 0x0044: return new Usage(this, id, "Tilt (Rotation)", UsageTypes.DV); 64 | case 0x0046: return new Usage(this, id, "Top Corner Distortion Control", UsageTypes.DV); 65 | case 0x0048: return new Usage(this, id, "Top Corner Distortion Balance", UsageTypes.DV); 66 | case 0x004a: return new Usage(this, id, "Bottom Corner Distortion Control", UsageTypes.DV); 67 | case 0x004c: return new Usage(this, id, "Bottom Corner Distortion Balance", UsageTypes.DV); 68 | case 0x0056: return new Usage(this, id, "Horizontal Moiré", UsageTypes.DV); 69 | case 0x0058: return new Usage(this, id, "Vertical Moiré", UsageTypes.DV); 70 | case 0x005e: return new Usage(this, id, "Input Level Select", UsageTypes.NAry); 71 | case 0x0060: return new Usage(this, id, "Input Source Select", UsageTypes.NAry); 72 | case 0x006c: return new Usage(this, id, "Red Video Black Level", UsageTypes.DV); 73 | case 0x006e: return new Usage(this, id, "Green Video Black Level", UsageTypes.DV); 74 | case 0x0070: return new Usage(this, id, "Blue Video Black Level", UsageTypes.DV); 75 | case 0x00a2: return new Usage(this, id, "Auto Size Center", UsageTypes.NAry); 76 | case 0x00a4: return new Usage(this, id, "Polarity Horizontal Synchronization", UsageTypes.NAry); 77 | case 0x00a6: return new Usage(this, id, "Polarity Vertical Synchronization", UsageTypes.NAry); 78 | case 0x00a8: return new Usage(this, id, "Synchronization Type", UsageTypes.NAry); 79 | case 0x00aa: return new Usage(this, id, "Screen Orientation", UsageTypes.NAry); 80 | case 0x00ac: return new Usage(this, id, "Horizontal Frequency", UsageTypes.DV); 81 | case 0x00ae: return new Usage(this, id, "Vertical Frequency", UsageTypes.DV); 82 | case 0x00b0: return new Usage(this, id, "Settings", UsageTypes.NAry); 83 | case 0x00ca: return new Usage(this, id, "On Screen Display", UsageTypes.NAry); 84 | case 0x00d4: return new Usage(this, id, "Stereo Mode", UsageTypes.NAry); 85 | } 86 | 87 | return base.CreateUsage(id); 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/VRControlsPage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Usages 14 | { 15 | // 16 | // VR Controls Usage Page. 17 | // 18 | [Description("VR Controls Usage Page")] 19 | public enum VRControlsPage : uint 20 | { 21 | // 22 | // Undefined Usage. 23 | // 24 | [Description("Undefined")] 25 | Undefined = 0x00030000, 26 | 27 | // 28 | // Belt Usage. 29 | // 30 | [Description("Belt")] 31 | Belt = 0x00030001, 32 | 33 | // 34 | // Body Suit Usage. 35 | // 36 | [Description("Body Suit")] 37 | BodySuit = 0x00030002, 38 | 39 | // 40 | // Flexor Usage. 41 | // 42 | [Description("Flexor")] 43 | Flexor = 0x00030003, 44 | 45 | // 46 | // Glove Usage. 47 | // 48 | [Description("Glove")] 49 | Glove = 0x00030004, 50 | 51 | // 52 | // Head Tracker Usage. 53 | // 54 | [Description("Head Tracker")] 55 | HeadTracker = 0x00030005, 56 | 57 | // 58 | // Head Mounted Display Usage. 59 | // 60 | [Description("Head Mounted Display")] 61 | HeadMountedDisplay = 0x00030006, 62 | 63 | // 64 | // Hand Tracker Usage. 65 | // 66 | [Description("Hand Tracker")] 67 | HandTracker = 0x00030007, 68 | 69 | // 70 | // Oculometer Usage. 71 | // 72 | [Description("Oculometer")] 73 | Oculometer = 0x00030008, 74 | 75 | // 76 | // Vest Usage. 77 | // 78 | [Description("Vest")] 79 | Vest = 0x00030009, 80 | 81 | // 82 | // Animatronic Device Usage. 83 | // 84 | [Description("Animatronic Device")] 85 | AnimatronicDevice = 0x0003000a, 86 | 87 | // 88 | // Stereo Enable Usage. 89 | // 90 | [Description("Stereo Enable")] 91 | StereoEnable = 0x00030020, 92 | 93 | // 94 | // Display Enable Usage. 95 | // 96 | [Description("Display Enable")] 97 | DisplayEnable = 0x00030021 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator/VRControlsUsagePage.g.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | // Specification revision: 1.5.0; generated at 2024-01-08 23:33:15Z. 5 | 6 | #pragma warning disable CS0108 // Member hides inherited member; missing new keyword 7 | 8 | using System; 9 | using System.Collections.Concurrent; 10 | using System.Collections.Generic; 11 | using System.ComponentModel; 12 | 13 | namespace DevDecoder.HIDDevices.Pages 14 | { 15 | using DevDecoder.HIDDevices.Usages; 16 | 17 | // 18 | // VR Controls Usage Page. 19 | // 20 | public sealed class VRControlsUsagePage : UsagePage 21 | { 22 | // 23 | // Singleton instance of VR Controls Usage Page. 24 | // 25 | public static readonly VRControlsUsagePage Instance = new(); 26 | 27 | // 28 | // Create singleton. 29 | // 30 | private VRControlsUsagePage() : base(0x0003, "VR Controls") 31 | { 32 | } 33 | 34 | /// 35 | protected override Usage CreateUsage(ushort id) 36 | { 37 | switch (id) 38 | { 39 | case 0x0000: return new Usage(this, id, "Undefined", UsageTypes.None); 40 | case 0x0001: return new Usage(this, id, "Belt", UsageTypes.CA); 41 | case 0x0002: return new Usage(this, id, "Body Suit", UsageTypes.CA); 42 | case 0x0003: return new Usage(this, id, "Flexor", UsageTypes.CP); 43 | case 0x0004: return new Usage(this, id, "Glove", UsageTypes.CA); 44 | case 0x0005: return new Usage(this, id, "Head Tracker", UsageTypes.CP); 45 | case 0x0006: return new Usage(this, id, "Head Mounted Display", UsageTypes.CA); 46 | case 0x0007: return new Usage(this, id, "Hand Tracker", UsageTypes.CA); 47 | case 0x0008: return new Usage(this, id, "Oculometer", UsageTypes.CA); 48 | case 0x0009: return new Usage(this, id, "Vest", UsageTypes.CA); 49 | case 0x000a: return new Usage(this, id, "Animatronic Device", UsageTypes.CA); 50 | case 0x0020: return new Usage(this, id, "Stereo Enable", UsageTypes.OOC); 51 | case 0x0021: return new Usage(this, id, "Display Enable", UsageTypes.OOC); 52 | } 53 | 54 | return base.CreateUsage(id); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /HIDDevices.Usages/Generated/hut1_5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevDecoder/HIDDevices/f779d27a284e1bcf5a63510a57cf60440a172655/HIDDevices.Usages/Generated/hut1_5.pdf -------------------------------------------------------------------------------- /HIDDevices.Usages/HIDDevices.Usages.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.1 4 | latest 5 | enable 6 | HIDDevices.Usages 7 | Craig Dean 8 | DevDecoder 9 | Cross-platform .NET Standard library which encodes the HID Usage Tables. 10 | https://github.com/DevDecoder/HIDDevices 11 | Cross-platform .NET Standard library which encodes the HID Usage Tables. 12 | 2020-2024 Craig Dean 13 | Apache-2.0 14 | https://github.com/DevDecoder/HIDDevices 15 | true 16 | true 17 | git 18 | Gamepad, Joystick, HID, HIDSharp, .NET, Cross-platform, USB 19 | DevDecoder Icon.png 20 | Stable release. 21 | true 22 | false 23 | true 24 | true 25 | snupkg 26 | DevDecoder.HIDDevices.Usages 27 | DevDecoder.HIDDevices 28 | readme.md 29 | Debug;Release;GenerateFromCache;GenerateFromSource 30 | 31 | 32 | true 33 | 34 | 35 | 36 | true 37 | 38 | 39 | true 40 | Generated 41 | $(MSBuildProjectDirectory)\..\HIDUsageTablesPDF.url 42 | 43 | $([System.IO.File]::ReadAllText($(HIDUsageTablesURL))) 44 | HidUsageTables.json 45 | 46 | $(CompilerGeneratedFilesOutputPath) 47 | 48 | 16 49 | 50 | true 51 | 52 | 53 | 54 | 55 | all 56 | runtime; build; native; contentfiles; analyzers; buildtransitive 57 | 58 | 59 | 60 | 61 | True 62 | \ 63 | 64 | 65 | True 66 | \ 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /HIDDevices.Usages/UsagePage.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections; 6 | using System.Collections.Concurrent; 7 | using System.Collections.Generic; 8 | 9 | namespace DevDecoder.HIDDevices; 10 | 11 | /// 12 | /// Class UsagePage. This class cannot be inherited. 13 | /// Implements the interface. 14 | /// Implements the interface. 15 | /// Base class for a collection of Usages. 16 | /// 17 | /// 18 | /// 19 | /// 20 | public partial class UsagePage : IEnumerable, IEquatable 21 | { 22 | protected readonly ConcurrentDictionary Usages = new(); 23 | 24 | protected UsagePage(ushort id, string name) 25 | { 26 | Id = id; 27 | Name = name; 28 | } 29 | 30 | /// 31 | /// Gets the identifier. 32 | /// 33 | /// The identifier. 34 | public ushort Id { get; } 35 | 36 | /// 37 | /// Gets the name. 38 | /// 39 | /// The name. 40 | public string Name { get; } 41 | 42 | /// 43 | /// Gets all currently available usage pages. 44 | /// 45 | /// A collection of usage pages. 46 | public static ICollection All => s_pages.Values; 47 | 48 | /// 49 | public IEnumerator GetEnumerator() => Usages.Values.GetEnumerator(); 50 | 51 | /// 52 | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); 53 | 54 | /// 55 | public bool Equals(UsagePage? other) => other is not null && (ReferenceEquals(this, other) || Id == other.Id); 56 | 57 | /// 58 | /// Gets the usage with the specified identifier. 59 | /// 60 | /// The identifier. 61 | /// UsagePage. 62 | public static UsagePage Get(ushort id) 63 | => s_pages.GetOrAdd(id, i => i < 0xFF00 64 | ? new UsagePage(i, $"Reserved (0x{id:X4})") 65 | : new UsagePage(i, $"Vendor-defined (0x{id:X4})")); 66 | 67 | /// 68 | /// Gets the usage with the specified usage enum. 69 | /// 70 | /// The usage. 71 | /// UsagePage. 72 | public static UsagePage Get(Enum usage) => Get((ushort)(Convert.ToUInt32(usage) >> 16)); 73 | 74 | /// 75 | /// Gets the usage with the specified full identifier. 76 | /// 77 | /// The full identifier. 78 | /// UsagePage. 79 | public static UsagePage Get(uint fullId) => Get((ushort)(fullId >> 16)); 80 | 81 | /// 82 | /// Gets the usage from this page with the specified identifier. 83 | /// 84 | /// The identifier. 85 | /// Usage. 86 | public Usage GetUsage(ushort id) => 87 | Usages.GetOrAdd(id, CreateUsage); 88 | 89 | /// 90 | /// Creates the usage with the specified id. 91 | /// 92 | /// The identifier. 93 | /// Usage. 94 | protected virtual Usage CreateUsage(ushort id) => 95 | new(this, id, $"Undefined (0x{id:X4})", UsageTypes.None); 96 | 97 | /// 98 | public override bool Equals(object? obj) => 99 | ReferenceEquals(this, obj) || (obj is UsagePage other && Equals(other)); 100 | 101 | /// 102 | public override int GetHashCode() => Id; 103 | 104 | /// 105 | /// Implements the == operator. 106 | /// 107 | /// The left. 108 | /// The right. 109 | /// The result of the operator. 110 | public static bool operator ==(UsagePage? left, UsagePage? right) => Equals(left, right); 111 | 112 | /// 113 | /// Implements the != operator. 114 | /// 115 | /// The left. 116 | /// The right. 117 | /// The result of the operator. 118 | public static bool operator !=(UsagePage? left, UsagePage? right) => !Equals(left, right); 119 | 120 | /// 121 | /// Performs an implicit conversion from to . 122 | /// 123 | /// The page. 124 | /// The result of the conversion. 125 | public static implicit operator ushort(UsagePage page) => page.Id; 126 | 127 | /// 128 | /// Performs an implicit conversion from to . 129 | /// 130 | /// The page. 131 | /// The result of the conversion. 132 | public static implicit operator UsagePage(ushort page) => Get(page); 133 | 134 | /// 135 | /// Performs an implicit conversion from to . 136 | /// 137 | /// The page. 138 | /// The result of the conversion. 139 | public static implicit operator UsagePage(Enum page) => Get(page); 140 | 141 | /// 142 | public override string ToString() => Name; 143 | } 144 | -------------------------------------------------------------------------------- /HIDDevices.Usages/UsageTypeGroup.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | namespace DevDecoder.HIDDevices; 5 | 6 | /// 7 | /// Enum UsageTypeGroup groups . 8 | /// 9 | public enum UsageTypeGroup : byte 10 | { 11 | /// 12 | /// The controls group. 13 | /// 14 | Controls, 15 | 16 | /// 17 | /// The data group. 18 | /// 19 | Data, 20 | 21 | /// 22 | /// The collections group. 23 | /// 24 | Collections 25 | } 26 | -------------------------------------------------------------------------------- /HIDDevices.Usages/UsageTypes.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace DevDecoder.HIDDevices; 8 | 9 | /// 10 | /// Enum UsageTypes defines usage types. 11 | /// 12 | /// 13 | [Flags] 14 | public enum UsageTypes : ushort 15 | { 16 | /// 17 | /// Indicates no usage types specified. 18 | /// 19 | [Description("None")] None = 0, 20 | 21 | /// 22 | /// The Linear Control usage type. 23 | /// 24 | [Description("Linear Control")] LC, 25 | 26 | /// 27 | /// The On/Off Control usage type. 28 | /// 29 | [Description("On/Off Control")] OOC, 30 | 31 | /// 32 | /// The Momentary Control usage type. 33 | /// 34 | [Description("Momentary Control")] MC, 35 | 36 | /// 37 | /// The One Shot Control usage type. 38 | /// 39 | [Description("One Shot Control")] OSC, 40 | 41 | /// 42 | /// The Re-trigger Control usage type. 43 | /// 44 | [Description("Re-trigger Control")] RTC, 45 | 46 | /// 47 | /// The Selector usage type. 48 | /// 49 | [Description("Selector")] Sel, 50 | 51 | /// 52 | /// The Static Value usage type. 53 | /// 54 | [Description("Static Value")] SV, 55 | 56 | /// 57 | /// The Static Flag usage type. 58 | /// 59 | [Description("Static Flag")] SF, 60 | 61 | /// 62 | /// The Dynamic Value usage type. 63 | /// 64 | [Description("Dynamic Value")] DV, 65 | 66 | /// 67 | /// The Dynamic Flag usage type. 68 | /// 69 | [Description("Dynamic Flag")] DF, 70 | 71 | /// 72 | /// The Dynamic Flag usage type. 73 | /// 74 | [Description("Buffered Bytes")] BufferedBytes, 75 | 76 | /// 77 | /// The Named Array usage type. 78 | /// 79 | [Description("Named Array")] NAry, 80 | 81 | /// 82 | /// The Application Collection usage type. 83 | /// 84 | [Description("Application Collection")] 85 | CA, 86 | 87 | /// 88 | /// The Logical Collection usage type. 89 | /// 90 | [Description("Logical Collection")] CL, 91 | 92 | /// 93 | /// The Physical Collection usage type. 94 | /// 95 | [Description("Physical Collection")] CP, 96 | 97 | /// 98 | /// The Usage Switch usage type. 99 | /// 100 | [Description("Usage Switch")] US, 101 | 102 | /// 103 | /// The Usage Modifier usage type. 104 | /// 105 | [Description("Usage Modifier")] UM 106 | } 107 | -------------------------------------------------------------------------------- /HIDDevices.Usages/readme.md: -------------------------------------------------------------------------------- 1 | [![Publish](https://github.com/DevDecoder/HIDDevices/workflows/Build%20and%20Publish%20HIDDevices.Usages/badge.svg)](https://github.com/DevDecoder/HIDDevices/actions?query=workflow:"Build+and+Publish+HIDDevices.Usages") 2 | [![GitHub tag](https://img.shields.io/github/tag/DevDecoder/HIDDevices?include_prereleases=&sort=semver&color=blue)](https://github.com/DevDecoder/HIDDevices/releases/) 3 | [![NuGet](https://img.shields.io/nuget/v/HIDDevices.Usages)](https://www.nuget.org/packages/HIDDevices.Usages/) 4 | [![License](https://img.shields.io/badge/License-Apache-blue)](#license) 5 | 6 | # Description 7 | 8 | This library provides a cross-platform .NET Standard encoding of the [the USB HID Usage Tables](https://usb.org/hid). It 9 | is a companion NuGet for [HIDDevices](https://www.nuget.org/packages/HIDDevices/), though it can be used on it's own. 10 | 11 | The latest USB specification PDF URL that was used for auto-generation can be found in 12 | [HIDUsageTablesPDF.url](https://github.com/DevDecoder/HIDDevices/blob/master/HIDUsageTablesPDF.url), and the generated files found in 13 | [this folder](https://github.com/DevDecoder/HIDDevices/tree/master/HIDDevices.Usages/Generated/HIDDevices.Generator/HIDDevices.Generator.UsagePageGenerator) 14 | explicitly state the current specification and generation date in their headers. 15 | 16 | Publishing an updated NuGet whenever the specification changes is relatively quick, as the build process 17 | can download the raw PDF from [usb.org](https://usb.org) and generate new code automatically. Unfortunately, I do not 18 | monitor the specifications for updates, so please [create an issue](https://github.com/DevDecoder/HIDDevices/issues) if 19 | you would like to prompt me to update - I usually respond quickly. 20 | 21 | ### Usages 22 | 23 | For convenience, the full HID Usage tables are exposed and described via the `Usages`, `UsagePages` and `UsageTypes` 24 | classes. These can be retrieved directly using the `uint` identifier or the convenience enums, all of which have 25 | the `Page` suffix. 26 | 27 | ```csharp 28 | // The enums can be cast to a Usage to retrieve full information about the Usage and its page. 29 | Usage usage = ButtonPage.Button0; 30 | Console.WriteLine($"Usage: {usage.Name}; Page: {usage.Page.Name}"); 31 | ``` 32 | -------------------------------------------------------------------------------- /HIDDevices.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32630.192 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HIDDevices", "HIDDevices\HIDDevices.csproj", "{5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HIDDevices.Test", "HIDDevices.Test\HIDDevices.Test.csproj", "{95729392-466B-4985-8803-96AFA24F580E}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B4EC1C09-398A-4952-9937-2092FFAB70F2}" 11 | ProjectSection(SolutionItems) = preProject 12 | .editorconfig = .editorconfig 13 | DevDecoder Icon.png = DevDecoder Icon.png 14 | HIDUsageTablesPDF.url = HIDUsageTablesPDF.url 15 | LICENSE.txt = LICENSE.txt 16 | NOTICE.txt = NOTICE.txt 17 | .github\workflows\publish.yml = .github\workflows\publish.yml 18 | .github\workflows\publishusages.yml = .github\workflows\publishusages.yml 19 | .github\workflows\validate.yml = .github\workflows\validate.yml 20 | version.json = version.json 21 | EndProjectSection 22 | EndProject 23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HIDDevices.Sample", "HIDDevices.Sample\HIDDevices.Sample.csproj", "{0E520169-5E25-43C5-BFD3-53FA4D4FF190}" 24 | EndProject 25 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HIDDevices.Generator", "HIDDevices.Generator\HIDDevices.Generator.csproj", "{9C8AD226-E52C-411E-9F05-1211754EEBDC}" 26 | EndProject 27 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HIDDevices.Usages", "HIDDevices.Usages\HIDDevices.Usages.csproj", "{A23FD533-C040-421E-977C-6F083AB3E182}" 28 | EndProject 29 | Global 30 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 31 | Debug|Any CPU = Debug|Any CPU 32 | GenerateFromCache|Any CPU = GenerateFromCache|Any CPU 33 | GenerateFromSource|Any CPU = GenerateFromSource|Any CPU 34 | Release|Any CPU = Release|Any CPU 35 | EndGlobalSection 36 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 37 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.GenerateFromCache|Any CPU.ActiveCfg = GenerateFromCache|Any CPU 40 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.GenerateFromCache|Any CPU.Build.0 = GenerateFromCache|Any CPU 41 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.GenerateFromSource|Any CPU.ActiveCfg = GenerateFromSource|Any CPU 42 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.GenerateFromSource|Any CPU.Build.0 = GenerateFromSource|Any CPU 43 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {5BE3CAC9-DB63-4A23-869E-9A97B8B5E6ED}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {95729392-466B-4985-8803-96AFA24F580E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {95729392-466B-4985-8803-96AFA24F580E}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {95729392-466B-4985-8803-96AFA24F580E}.GenerateFromCache|Any CPU.ActiveCfg = GenerateFromCache|Any CPU 48 | {95729392-466B-4985-8803-96AFA24F580E}.GenerateFromCache|Any CPU.Build.0 = GenerateFromCache|Any CPU 49 | {95729392-466B-4985-8803-96AFA24F580E}.GenerateFromSource|Any CPU.ActiveCfg = GenerateFromSource|Any CPU 50 | {95729392-466B-4985-8803-96AFA24F580E}.GenerateFromSource|Any CPU.Build.0 = GenerateFromSource|Any CPU 51 | {95729392-466B-4985-8803-96AFA24F580E}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {95729392-466B-4985-8803-96AFA24F580E}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 54 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.Debug|Any CPU.Build.0 = Debug|Any CPU 55 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.GenerateFromCache|Any CPU.ActiveCfg = GenerateFromCache|Any CPU 56 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.GenerateFromSource|Any CPU.ActiveCfg = GenerateFromSource|Any CPU 57 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {0E520169-5E25-43C5-BFD3-53FA4D4FF190}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 60 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.GenerateFromCache|Any CPU.ActiveCfg = GenerateFromCache|Any CPU 61 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.GenerateFromCache|Any CPU.Build.0 = GenerateFromCache|Any CPU 62 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.GenerateFromSource|Any CPU.ActiveCfg = GenerateFromSource|Any CPU 63 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.GenerateFromSource|Any CPU.Build.0 = GenerateFromSource|Any CPU 64 | {9C8AD226-E52C-411E-9F05-1211754EEBDC}.Release|Any CPU.ActiveCfg = Release|Any CPU 65 | {A23FD533-C040-421E-977C-6F083AB3E182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 66 | {A23FD533-C040-421E-977C-6F083AB3E182}.Debug|Any CPU.Build.0 = Debug|Any CPU 67 | {A23FD533-C040-421E-977C-6F083AB3E182}.GenerateFromCache|Any CPU.ActiveCfg = GenerateFromCache|Any CPU 68 | {A23FD533-C040-421E-977C-6F083AB3E182}.GenerateFromCache|Any CPU.Build.0 = GenerateFromCache|Any CPU 69 | {A23FD533-C040-421E-977C-6F083AB3E182}.GenerateFromSource|Any CPU.ActiveCfg = GenerateFromSource|Any CPU 70 | {A23FD533-C040-421E-977C-6F083AB3E182}.GenerateFromSource|Any CPU.Build.0 = GenerateFromSource|Any CPU 71 | {A23FD533-C040-421E-977C-6F083AB3E182}.Release|Any CPU.ActiveCfg = Release|Any CPU 72 | {A23FD533-C040-421E-977C-6F083AB3E182}.Release|Any CPU.Build.0 = Release|Any CPU 73 | EndGlobalSection 74 | GlobalSection(SolutionProperties) = preSolution 75 | HideSolutionNode = FALSE 76 | EndGlobalSection 77 | GlobalSection(ExtensibilityGlobals) = postSolution 78 | SolutionGuid = {2BAF9F91-9982-4216-A784-7E6F34DD9E9D} 79 | EndGlobalSection 80 | EndGlobal 81 | -------------------------------------------------------------------------------- /HIDDevices/Attributes/ControlAttribute.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using DevDecoder.HIDDevices.Controllers; 8 | 9 | namespace DevDecoder.HIDDevices; 10 | 11 | /// 12 | /// Class ControlAttribute. This class cannot be inherited. 13 | /// Attribute that should be added to properties on a to indicate 14 | /// that they should be bound to a . 15 | /// 16 | /// 17 | /// Note that multiple usages can be supplied, any value that can be converted to a 18 | /// is supported, which includes the Usage enums. Further, the value must be the full ID, and encode 19 | /// the page and ID of the usage. 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | /// The usages. 28 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 29 | public sealed class ControlAttribute(params object[] usages) : Attribute 30 | { 31 | /// 32 | /// Gets or sets the weight, a higher weight will increase the scoring of controls matching this attribute, 33 | /// increasing their preference when selection when attaching to the associated property. 34 | /// 35 | /// The weight. 36 | public byte Weight { get; set; } = 1; 37 | 38 | /// 39 | /// Gets a list of valid usages, of which the device must match all. 40 | /// 41 | /// 42 | /// If alternative usages are to be supported, then multiple attributes can be added. When combined 43 | /// with the of each attribute, it allows for fine control of 44 | /// matching. 45 | /// 46 | public IReadOnlyList Usages { get; } = usages 47 | .Select(Convert.ToUInt32) 48 | .ToArray(); 49 | 50 | internal bool Matches(Control control) => Usages.All(usage => control.Usages.Contains(usage)); 51 | } 52 | -------------------------------------------------------------------------------- /HIDDevices/Attributes/DeviceAttribute.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text.RegularExpressions; 8 | using DevDecoder.HIDDevices.Controllers; 9 | 10 | namespace DevDecoder.HIDDevices; 11 | 12 | /// 13 | /// Class DeviceAttribute. This class cannot be inherited. 14 | /// Attribute that can optionally be added to a descendent to limit the 15 | /// Devices 16 | /// that can be matched by the controller. 17 | /// 18 | /// 19 | /// Note that multiple usages can be supplied, any value that can be converted to a 20 | /// is supported, which includes the Usage enums. Further, the value must be the full ID, and encode 21 | /// the page and ID of the usage. 22 | /// 23 | /// 24 | /// 25 | /// 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | /// The usages, all of which must match. 30 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 31 | public sealed class DeviceAttribute(params object[] usages) : Attribute 32 | { 33 | private Regex? _releaseNumberRegex; 34 | 35 | /// 36 | /// Gets a list of valid usages, of which the device must match all. 37 | /// 38 | /// If alternative usages are to be supported, then multiple attributes can be added. 39 | public IReadOnlyList Usages { get; } = usages 40 | .Select(Convert.ToUInt32) 41 | .ToArray(); 42 | 43 | /// 44 | /// Gets or sets an optional Product ID; 0 if any ID is valid. 45 | /// 46 | public int ProductId { get; set; } 47 | 48 | /// 49 | /// Gets or sets an optional to match a ; otherwise . 50 | /// 51 | public string? ReleaseNumberRegex { get; set; } 52 | 53 | internal bool Matches(Device device) 54 | { 55 | if ((ProductId > 0 && device.ProductId != ProductId) || 56 | !Usages.All(usage => device.Usages.Contains(usage))) 57 | { 58 | return false; 59 | } 60 | 61 | var releaseNumberRegex = _releaseNumberRegex; 62 | if (releaseNumberRegex is null) 63 | { 64 | if (string.IsNullOrWhiteSpace(ReleaseNumberRegex)) 65 | { 66 | // No regex to match. 67 | return true; 68 | } 69 | 70 | releaseNumberRegex = new Regex(ReleaseNumberRegex, RegexOptions.Compiled); 71 | _releaseNumberRegex = releaseNumberRegex; 72 | } 73 | 74 | return releaseNumberRegex.IsMatch(device.ReleaseNumber.ToString()); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /HIDDevices/ControlChange.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Diagnostics; 6 | using System.Threading; 7 | using HidSharp.Reports; 8 | 9 | namespace DevDecoder.HIDDevices; 10 | 11 | /// 12 | /// Struct ControlChange 13 | /// Implements the interface. 14 | /// Used to record a change in a Control's value. 15 | /// 16 | /// 17 | /// 18 | public readonly struct ControlChange : IEquatable 19 | { 20 | internal ControlChange(Control control, (DataValue value, long timestamp) value) : this() 21 | { 22 | Control = control; 23 | PreviousValue = double.NaN; 24 | Value = Control.Normalise(value.value.GetLogicalValue()); 25 | Timestamp = value.timestamp; 26 | } 27 | 28 | private ControlChange(Control control, double previousValue, double value, long timestamp) : this() 29 | { 30 | Control = control; 31 | PreviousValue = previousValue; 32 | Value = value; 33 | Timestamp = timestamp; 34 | } 35 | 36 | /// 37 | /// Gets the control. 38 | /// 39 | /// The control. 40 | public Control Control { get; } 41 | 42 | /// 43 | /// Gets the previous value. 44 | /// 45 | /// The previous value. 46 | public double PreviousValue { get; } 47 | 48 | /// 49 | /// Gets the value. 50 | /// 51 | /// The value. 52 | public double Value { get; } 53 | 54 | /// 55 | /// Gets the timestamp. 56 | /// 57 | /// The timestamp. 58 | public long Timestamp { get; } 59 | 60 | /// 61 | /// Gets the elapsed time since the change occurred. 62 | /// 63 | /// The elapsed time. 64 | public TimeSpan Elapsed => Timestamp < 0 65 | ? Timeout.InfiniteTimeSpan 66 | : TimeSpan.FromSeconds( 67 | (double)(Stopwatch.GetTimestamp() - Timestamp) / Stopwatch.Frequency); 68 | 69 | internal ControlChange? Update((DataValue value, long timestamp) value) 70 | { 71 | var normalisedValue = Control.Normalise(value.value.GetLogicalValue()); 72 | return normalisedValue.Equals(Value) 73 | ? null 74 | : new ControlChange(Control, Value, normalisedValue, value.timestamp); 75 | } 76 | 77 | /// 78 | public bool Equals(ControlChange other) 79 | => ReferenceEquals(Control, other.Control) && 80 | PreviousValue.Equals(other.PreviousValue) && 81 | Value.Equals(other.Value); 82 | 83 | /// 84 | public override bool Equals(object? obj) => obj is ControlChange other && Equals(other); 85 | 86 | /// 87 | public override int GetHashCode() => HashCode.Combine(Control, PreviousValue, Value); 88 | 89 | /// 90 | /// Implements the == operator. 91 | /// 92 | /// The left. 93 | /// The right. 94 | /// The result of the operator. 95 | public static bool operator ==(ControlChange left, ControlChange right) => left.Equals(right); 96 | 97 | /// 98 | /// Implements the != operator. 99 | /// 100 | /// The left. 101 | /// The right. 102 | /// The result of the operator. 103 | public static bool operator !=(ControlChange left, ControlChange right) => !left.Equals(right); 104 | 105 | /// 106 | /// Performs an implicit conversion from to . 107 | /// 108 | /// The change. 109 | /// The result of the conversion. 110 | public static implicit operator double(ControlChange change) => change.Value; 111 | 112 | /// 113 | /// Creates a change that simulates the current value having changed from . 114 | /// 115 | /// 116 | internal ControlChange Reset() => new(Control, double.NaN, Value, Timestamp); 117 | } 118 | -------------------------------------------------------------------------------- /HIDDevices/Controllers/ControlInfo.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | 7 | namespace DevDecoder.HIDDevices.Controllers; 8 | 9 | /// 10 | /// Class ControlInfo is used to indicate the relationship between a and a 11 | /// property on a . These are normally generated automatically, but can be created 12 | /// manually when creating a custom controller. 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The type of the property. 20 | /// Name of the property. 21 | /// The control. 22 | /// The converter. 23 | public class ControlInfo(Type type, string propertyName, Control control, TypeConverter? converter) 24 | { 25 | 26 | /// 27 | /// Gets the type. 28 | /// 29 | /// The type. 30 | public Type Type { get; } = type; 31 | 32 | /// 33 | /// Gets the name of the property. 34 | /// 35 | /// The name of the property. 36 | public string PropertyName { get; } = propertyName; 37 | 38 | /// 39 | /// Gets the control. 40 | /// 41 | /// The control. 42 | public Control Control { get; } = control; 43 | 44 | /// 45 | /// Gets the converter. 46 | /// 47 | /// The converter. 48 | public TypeConverter? Converter { get; } = converter; 49 | } 50 | 51 | /// 52 | /// Class ControlInfo. This class cannot be inherited. 53 | /// Generic version of for conveniently defining control infos. 54 | /// 55 | /// The property type. 56 | /// 57 | /// 58 | /// Initializes a new instance of the class. 59 | /// 60 | /// Name of the property. 61 | /// The control. 62 | /// The converter. 63 | public sealed class ControlInfo(string propertyName, Control control, TypeConverter? converter) : ControlInfo(typeof(T), propertyName, control, converter) 64 | { 65 | } 66 | -------------------------------------------------------------------------------- /HIDDevices/Controllers/ControlValue.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Diagnostics; 7 | 8 | namespace DevDecoder.HIDDevices.Controllers; 9 | 10 | /// 11 | /// Struct ControlValue holds the latest value of a for a 12 | /// . 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | public readonly struct ControlValue : IEquatable 19 | { 20 | internal ControlValue(ControlChange change, ControlInfo info, object? value) 21 | { 22 | Debug.Assert(ReferenceEquals(change.Control, info.Control)); 23 | Change = change; 24 | Info = info; 25 | Value = value; 26 | } 27 | 28 | /// 29 | /// Gets the type. 30 | /// 31 | /// The type. 32 | public Type Type => Info.Type; 33 | 34 | /// 35 | /// Gets the name of the property. 36 | /// 37 | /// The name of the property. 38 | public string PropertyName => Info.PropertyName; 39 | 40 | /// 41 | /// Gets the control. 42 | /// 43 | /// The control. 44 | public Control Control => Info.Control; 45 | 46 | /// 47 | /// Gets the timestamp. 48 | /// 49 | /// The timestamp. 50 | public long Timestamp => Change.Timestamp; 51 | 52 | /// 53 | /// Gets the elapsed. 54 | /// 55 | /// The elapsed. 56 | public TimeSpan Elapsed => Change.Elapsed; 57 | 58 | /// 59 | /// Gets the converter. 60 | /// 61 | /// The converter. 62 | public TypeConverter? Converter => Info.Converter; 63 | 64 | /// 65 | /// Gets the change. 66 | /// 67 | /// The change. 68 | public ControlChange Change { get; } 69 | 70 | /// 71 | /// Gets the control information. 72 | /// 73 | /// The control information. 74 | public ControlInfo Info { get; } 75 | 76 | /// 77 | /// Gets the value. 78 | /// 79 | /// The value. 80 | public object? Value { get; } 81 | 82 | /// 83 | public bool Equals(ControlValue other) => 84 | Change.Equals(other.Change) && Info.Equals(other.Info) && Equals(Value, other.Value); 85 | 86 | /// 87 | public override bool Equals(object? obj) => obj is ControlValue other && Equals(other); 88 | 89 | /// 90 | public override int GetHashCode() => HashCode.Combine(Change, Info, Value); 91 | 92 | /// 93 | /// Implements the == operator. 94 | /// 95 | /// The left. 96 | /// The right. 97 | /// The result of the operator. 98 | public static bool operator ==(ControlValue left, ControlValue right) => left.Equals(right); 99 | 100 | /// 101 | /// Implements the != operator. 102 | /// 103 | /// The left. 104 | /// The right. 105 | /// The result of the operator. 106 | public static bool operator !=(ControlValue left, ControlValue right) => !left.Equals(right); 107 | } 108 | -------------------------------------------------------------------------------- /HIDDevices/Controllers/CreateControllerDelegate.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace DevDecoder.HIDDevices.Controllers; 7 | 8 | /// 9 | /// Delegate CreateControllerDelegate used to define a method for creating a new from a 10 | /// . 11 | /// 12 | /// The controller type. 13 | /// The device. 14 | /// A controller; otherwise . 15 | /// 16 | /// 17 | [return: MaybeNull] 18 | public delegate T CreateControllerDelegate(Device device) where T : Controller?; 19 | -------------------------------------------------------------------------------- /HIDDevices/Converters/BooleanConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System.ComponentModel; 5 | using System.Globalization; 6 | 7 | namespace DevDecoder.HIDDevices.Converters; 8 | 9 | /// 10 | /// Class BooleanConverter converts control values to a boolean. This class cannot be inherited. 11 | /// Implements . 12 | /// 13 | public sealed class BooleanConverter : ControlConverter 14 | { 15 | /// 16 | /// The singleton instance of the converter. 17 | /// 18 | public static readonly BooleanConverter Instance = new(); 19 | 20 | private BooleanConverter() 21 | { 22 | } 23 | 24 | /// 25 | protected override bool Convert(ITypeDescriptorContext context, CultureInfo culture, double value) => 26 | !double.IsNaN(value) && value > 0.5D; 27 | } 28 | -------------------------------------------------------------------------------- /HIDDevices/Converters/ControlConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Globalization; 7 | 8 | namespace DevDecoder.HIDDevices.Converters; 9 | 10 | /// 11 | /// Class ControlConverter. 12 | /// Implements the 13 | /// Used to conveniently create control converters. 14 | /// 15 | /// The type of control property. 16 | /// 17 | public abstract class ControlConverter : TypeConverter 18 | { 19 | /// 20 | public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) => 21 | sourceType == typeof(double) || base.CanConvertFrom(context, sourceType); 22 | 23 | /// 24 | public override object? ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object? value) 25 | => value is double dv 26 | ? Convert(context, culture, dv) 27 | : base.ConvertFrom(context, culture, value); 28 | 29 | /// 30 | /// Converts the value to the specified type.. 31 | /// 32 | /// The context. 33 | /// The culture. 34 | /// The value. 35 | /// The value. 36 | protected virtual T? Convert(ITypeDescriptorContext context, CultureInfo culture, double value) => 37 | base.ConvertFrom(context, culture, value) is T v ? v : default; 38 | } 39 | -------------------------------------------------------------------------------- /HIDDevices/Converters/Direction.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | namespace DevDecoder.HIDDevices.Converters; 5 | 6 | /// 7 | /// Enum Direction indicates the possible directions of a Hat control. 8 | /// 9 | public enum Direction : byte 10 | { 11 | /// 12 | /// The north direction (or up). 13 | /// 14 | North = 0, 15 | 16 | /// 17 | /// The north east direction. 18 | /// 19 | NorthEast = 1, 20 | 21 | /// 22 | /// The east direction. 23 | /// 24 | East = 2, 25 | 26 | /// 27 | /// The south east direction. 28 | /// 29 | SouthEast = 3, 30 | 31 | /// 32 | /// The south direction. 33 | /// 34 | South = 4, 35 | 36 | /// 37 | /// The south west direction. 38 | /// 39 | SouthWest = 5, 40 | 41 | /// 42 | /// The west direction. 43 | /// 44 | West = 6, 45 | 46 | /// 47 | /// The north west direction. 48 | /// 49 | NorthWest = 7, 50 | 51 | /// 52 | /// The hat is not pressed. 53 | /// 54 | NotPressed = 255 55 | } 56 | -------------------------------------------------------------------------------- /HIDDevices/Converters/DirectionConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Globalization; 7 | 8 | namespace DevDecoder.HIDDevices.Converters; 9 | 10 | /// 11 | /// Class DirectionConverter converts control values to a . This class cannot be inherited. 12 | /// Implements the . 13 | /// 14 | /// 15 | /// 16 | public sealed class DirectionConverter : ControlConverter 17 | { 18 | /// 19 | /// The singleton instance of the converter. 20 | /// 21 | public static readonly DirectionConverter Instance = new(); 22 | 23 | private DirectionConverter() 24 | { 25 | } 26 | 27 | /// 28 | protected override Direction Convert(ITypeDescriptorContext context, CultureInfo culture, double value) => 29 | double.IsNaN(value) 30 | ? Direction.NotPressed 31 | : (Direction)Math.Clamp((int)Math.Round(value * 7.0), 0, 7); 32 | } 33 | -------------------------------------------------------------------------------- /HIDDevices/Converters/LeftTriggerConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | namespace DevDecoder.HIDDevices.Converters; 5 | 6 | /// 7 | /// Class LeftTriggerConverter converts control values for trigger properties. This class cannot be inherited. 8 | /// Implements the . 9 | /// 10 | /// 11 | /// 12 | public sealed class LeftTriggerConverter : RangeConverter 13 | { 14 | /// 15 | /// The singleton instance of the converter. 16 | /// 17 | public static readonly LeftTriggerConverter Instance = new(); 18 | 19 | private LeftTriggerConverter() : base(0D, 1D, 0.5D) 20 | { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /HIDDevices/Converters/RangeConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.ComponentModel; 6 | using System.Globalization; 7 | 8 | namespace DevDecoder.HIDDevices.Converters; 9 | 10 | /// 11 | /// Class RangeConverter converts control values to a range. This class cannot be inherited. 12 | /// Implements the . 13 | /// 14 | /// 15 | public class RangeConverter : ControlConverter 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The minimum. 21 | /// The maximum. 22 | /// The input minimum. 23 | /// The input maximum. 24 | /// outputMaximum 25 | public RangeConverter( 26 | double outputMinimum, 27 | double outputMaximum, 28 | double inputMinimum = 0D, 29 | double inputMaximum = 1D) 30 | { 31 | if (inputMaximum < 0D) 32 | { 33 | inputMinimum = 0D; 34 | } 35 | else if (inputMinimum > 1D) 36 | { 37 | inputMinimum = 1D; 38 | } 39 | 40 | if (inputMaximum < 0D) 41 | { 42 | inputMaximum = 0D; 43 | } 44 | else if (inputMaximum > 1D) 45 | { 46 | inputMaximum = 1D; 47 | } 48 | 49 | if (inputMaximum < inputMinimum) 50 | { 51 | // Flip both input and output ranges so input range always has min 66 | /// Gets the input minimum. 67 | /// 68 | /// The input minimum. 69 | public double InputMinimum { get; } 70 | 71 | /// 72 | /// Gets the input maximum. 73 | /// 74 | /// The input maximum. 75 | public double InputMaximum { get; } 76 | 77 | /// 78 | /// Gets the input range. 79 | /// 80 | /// The input range. 81 | public double InputRange { get; } 82 | 83 | /// 84 | /// Gets the output minimum. 85 | /// 86 | /// The output minimum. 87 | public double OutputMinimum { get; } 88 | 89 | /// 90 | /// Gets the output maximum. 91 | /// 92 | /// The output maximum. 93 | public double OutputMaximum { get; } 94 | 95 | /// 96 | /// Gets the output range. 97 | /// 98 | /// The output range. 99 | public double OutputRange { get; } 100 | 101 | /// 102 | protected override double Convert(ITypeDescriptorContext context, CultureInfo culture, double value) 103 | { 104 | if (double.IsNaN(value)) 105 | { 106 | return double.NaN; 107 | } 108 | 109 | if (value <= InputMinimum) 110 | { 111 | return OutputMinimum; 112 | } 113 | 114 | if (value >= InputMaximum) 115 | { 116 | return OutputMaximum; 117 | } 118 | 119 | return OutputMinimum + (value - InputMinimum) / InputRange * OutputRange; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /HIDDevices/Converters/RightTriggerConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | namespace DevDecoder.HIDDevices.Converters; 5 | 6 | /// 7 | /// Class RightTriggerConverter converts control values for trigger properties. This class cannot be inherited. 8 | /// Implements the . 9 | /// 10 | /// 11 | /// 12 | public sealed class RightTriggerConverter : RangeConverter 13 | { 14 | /// 15 | /// The singleton instance of the converter. 16 | /// 17 | public static readonly RightTriggerConverter Instance = new(); 18 | 19 | public RightTriggerConverter() : base(0D, 1D, 0.5D, 0D) 20 | { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /HIDDevices/Converters/SignedConverter.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | namespace DevDecoder.HIDDevices.Converters; 5 | 6 | /// 7 | /// Class SignedConverter converts control values to a property value between -1 and 1, centred on 0. This class cannot 8 | /// be inherited. 9 | /// Implements the . 10 | /// 11 | /// 12 | /// 13 | public sealed class SignedConverter : RangeConverter 14 | { 15 | /// 16 | /// The singleton instance of the converter. 17 | /// 18 | public static readonly SignedConverter Instance = new(); 19 | 20 | private SignedConverter() : base(-1D, 1D) 21 | { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /HIDDevices/HIDDevices.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netstandard2.1 4 | latest 5 | enable 6 | HIDDevices 7 | Craig Dean 8 | DevDecoder 9 | Cross-platform .NET Standard library for asynchronous access to HID Devices (e.g. gamepads, joysticks, etc.) 10 | https://github.com/DevDecoder/HIDDevices 11 | Cross-platform .NET Standard library for asynchronous access to HID Devices (e.g. gamepads, joysticks, etc.) 12 | 2020-2024 Craig Dean 13 | Apache-2.0 14 | https://github.com/DevDecoder/HIDDevices 15 | true 16 | true 17 | git 18 | Gamepad, Joystick, HID, HIDSharp, .NET, Cross-platform, USB 19 | DevDecoder Icon.png 20 | Stable release. 21 | true 22 | false 23 | true 24 | true 25 | snupkg 26 | DevDecoder.HIDDevices 27 | DevDecoder.HIDDevices 28 | readme.md 29 | Debug;Release;GenerateFromCache;GenerateFromSource 30 | 31 | IDE0130 32 | 33 | 34 | true 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | all 44 | runtime; build; native; contentfiles; analyzers; buildtransitive 45 | 46 | 47 | 48 | 49 | 50 | 51 | True 52 | \ 53 | 54 | 55 | True 56 | \ 57 | 58 | 59 | 60 | 61 | True 62 | True 63 | Resources.resx 64 | 65 | 66 | 67 | 68 | ResXFileCodeGenerator 69 | Resources.Designer.cs 70 | 71 | 72 | -------------------------------------------------------------------------------- /HIDDevices/HIDDevices.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  5 | True 6 | False 7 | True -------------------------------------------------------------------------------- /HIDDevices/LoggingExtensions.cs: -------------------------------------------------------------------------------- 1 | // Licensed under the Apache License, Version 2.0 (the "License"). 2 | // See the LICENSE file in the project root for more information. 3 | 4 | using System; 5 | using System.Runtime.CompilerServices; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace DevDecoder.HIDDevices; 9 | 10 | internal static class LoggingExtensions 11 | { 12 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 13 | public static void Log(this ILogger logger, Event @event, params object[] args) => @event.Log(logger, args); 14 | 15 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 16 | public static void Log(this ILogger logger, Event @event, Exception exception, params object[] args) => 17 | @event.Log(logger, exception, args); 18 | } 19 | -------------------------------------------------------------------------------- /HIDUsageTablesPDF.url: -------------------------------------------------------------------------------- 1 | https://usb.org/sites/default/files/hut1_5.pdf -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | HIDDevices 2 | Copyright 2020-2021 Craig Dean 3 | -------------------------------------------------------------------------------- /version.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", 3 | "version": "4.1", 4 | "publicReleaseRefSpec": [ 5 | "^refs/heads/master$", 6 | "^refs/heads/v\\d+(?:\\.\\d+)?$" 7 | ], 8 | "cloudBuild": { 9 | "buildNumber": { 10 | "enabled": true 11 | } 12 | } 13 | } --------------------------------------------------------------------------------