Repository: mfakane/rawinput-sharp
Branch: master
Commit: a6ed7b2ce410
Files: 86
Total size: 131.6 KB
Directory structure:
gitextract_swu12hhg/
├── .gitattributes
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── RawInput.Sharp/
│ ├── EnvironmentEx.cs
│ ├── HidButton.cs
│ ├── HidButtonSet.cs
│ ├── HidButtonSetState.cs
│ ├── HidButtonState.cs
│ ├── HidPreparsedByteArrayData.cs
│ ├── HidReader.cs
│ ├── HidUsageAndPage.cs
│ ├── HidValue.cs
│ ├── HidValueSet.cs
│ ├── HidValueSetState.cs
│ ├── HidValueState.cs
│ ├── IHidPreparsedData.cs
│ ├── MarshalEx.cs
│ ├── Native/
│ │ ├── CfgMgr32.cs
│ │ ├── ConfigReturnValue.cs
│ │ ├── DeviceInstanceHandle.cs
│ │ ├── DevicePropertyKey.cs
│ │ ├── HidD.cs
│ │ ├── HidDeviceHandle.cs
│ │ ├── HidP.cs
│ │ ├── HidPButtonCaps.cs
│ │ ├── HidPCaps.cs
│ │ ├── HidPCapsNotRange.cs
│ │ ├── HidPCapsRange.cs
│ │ ├── HidPReportType.cs
│ │ ├── HidPValueCaps.cs
│ │ ├── HidPreparsedData.cs
│ │ ├── Kernel32.cs
│ │ ├── NtStatus.cs
│ │ ├── RawHid.cs
│ │ ├── RawInputDeviceHandle.cs
│ │ ├── RawInputDeviceInfo.cs
│ │ ├── RawInputDeviceInfoBehavior.cs
│ │ ├── RawInputDeviceListItem.cs
│ │ ├── RawInputHandle.cs
│ │ ├── RawInputHeader.cs
│ │ ├── RawInputHidInfo.cs
│ │ ├── RawInputKeyboardInfo.cs
│ │ ├── RawInputMouseInfo.cs
│ │ ├── RawKeyboard.cs
│ │ ├── RawMouse.cs
│ │ ├── User32.cs
│ │ └── Win32ErrorException.cs
│ ├── RawInput.Sharp.csproj
│ ├── RawInputData.cs
│ ├── RawInputDevice.cs
│ ├── RawInputDeviceFlags.cs
│ ├── RawInputDeviceRegistration.cs
│ ├── RawInputDeviceType.cs
│ ├── RawInputDigitizer.cs
│ ├── RawInputDigitizerButton.cs
│ ├── RawInputDigitizerContact.cs
│ ├── RawInputDigitizerContactKind.cs
│ ├── RawInputDigitizerData.cs
│ ├── RawInputHid.cs
│ ├── RawInputHidData.cs
│ ├── RawInputKeyboard.cs
│ ├── RawInputKeyboardData.cs
│ ├── RawInputMouse.cs
│ └── RawInputMouseData.cs
├── RawInput.Sharp.DigitizerExample/
│ ├── MainForm.Designer.cs
│ ├── MainForm.cs
│ ├── MainForm.resx
│ ├── Program.cs
│ └── RawInput.Sharp.DigitizerExample.csproj
├── RawInput.Sharp.SimpleExample/
│ ├── Program.cs
│ ├── RawInput.Sharp.SimpleExample.csproj
│ ├── RawInputEventArgs.cs
│ ├── RawInputReceiverWindow.cs
│ └── app.config
├── RawInput.Sharp.SimpleExample.WPF/
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── AssemblyInfo.cs
│ ├── MainWindow.xaml
│ ├── MainWindow.xaml.cs
│ └── RawInput.Sharp.SimpleExample.WPF.csproj
├── RawInput.Sharp.SimpleExample.Win32/
│ ├── Program.cs
│ └── RawInput.Sharp.SimpleExample.Win32.csproj
├── RawInput.Sharp.sln
└── renovate.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
================================================
FILE: .github/FUNDING.yml
================================================
github: [mfakane]
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
================================================
FILE: LICENSE.txt
================================================
The zlib License
Copyright (c) 2019 mfakane
This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use of
this software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to
the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim
that you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated but is
not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
================================================
FILE: README.md
================================================
# RawInput.Sharp
A simple wrapper library for Windows [Raw Input](https://learn.microsoft.com/en-us/windows/win32/inputdev/raw-input).
Available on .NET Standard 1.1 and .NET Framework 4.6.1.
## NuGet
https://www.nuget.org/packages/RawInput.Sharp/
## Usage
### Acquiring connected devices
```cs
// using Linearstar.Windows.RawInput;
// Get the devices that can be handled with Raw Input.
var devices = RawInputDevice.GetDevices();
// Keyboards will be returned as RawInputKeyboard.
var keyboards = devices.OfType<RawInputKeyboard>();
// Mice will be RawInputMouse.
var mice = devices.OfType<RawInputMouse>();
```
### Reading raw inputs
```cs
protected override void WndProc(ref Message m)
{
const int WM_INPUT = 0x00FF;
// You can read inputs by processing the WM_INPUT message.
if (m.Msg == WM_INPUT)
{
// Create an RawInputData from the handle stored in lParam.
var data = RawInputData.FromHandle(m.LParam);
// You can identify the source device using Header.DeviceHandle or just Device.
var sourceDeviceHandle = data.Header.DeviceHandle;
var sourceDevice = data.Device;
// The data will be an instance of either RawInputMouseData, RawInputKeyboardData, or RawInputHidData.
// They contain the raw input data in their properties.
switch (data)
{
case RawInputMouseData mouse:
Console.WriteLine(mouse.Mouse);
break;
case RawInputKeyboardData keyboard:
Console.WriteLine(keyboard.Keyboard);
break;
case RawInputHidData hid:
Console.WriteLine(hid.Hid);
break;
}
}
base.WndProc(ref m);
}
```
### Further examples
- [RawInput.Sharp.SimpleExample](RawInput.Sharp.SimpleExample)
- A simple example that shows keyboard input events.
- [RawInput.Sharp.SimpleExample.WPF](RawInput.Sharp.SimpleExample.WPF)
- WPF version of the prior one.
- [RawInput.Sharp.DigitizerExample](RawInput.Sharp.DigitizerExample)
- An example handling digitizers, such as pen tablets, touch screens, and touch pads.
## License
[zlib License](LICENSE.txt)
================================================
FILE: RawInput.Sharp/EnvironmentEx.cs
================================================
using System;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
static class EnvironmentEx
{
public static bool Is64BitOperatingSystem
{
get
{
var isWow64ProcessProc = Kernel32.GetProcAddress(Kernel32.GetModuleHandle("kernel32"), "IsWow64Process");
return isWow64ProcessProc != IntPtr.Zero
&& Kernel32.IsWow64Process(Kernel32.GetCurrentProcess());
}
}
public static bool Is64BitProcess => IntPtr.Size == 8;
}
================================================
FILE: RawInput.Sharp/HidButton.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidButton
{
internal readonly HidReader reader;
internal readonly HidPButtonCaps buttonCaps;
public int ReportId => buttonCaps.ReportID;
public HidUsageAndPage UsageAndPage { get; }
public HidUsageAndPage LinkUsageAndPage => new(buttonCaps.LinkUsagePage, buttonCaps.LinkUsage);
public int LinkCollection => buttonCaps.LinkCollection;
internal HidButton(HidReader reader, HidPButtonCaps buttonCaps, ushort usage)
{
this.reader = reader;
this.buttonCaps = buttonCaps;
UsageAndPage = new HidUsageAndPage(buttonCaps.UsagePage, usage);
}
public HidButtonState GetState(ArraySegment<byte> report) =>
GetState(report.ToArray(), report.Count);
public HidButtonState GetState(byte[] report, int reportLength) =>
new(this, report, reportLength);
public override string ToString() =>
$"{ReportId}, {LinkCollection}, Link: {{{LinkUsageAndPage}}}, Usage: {{{UsageAndPage}}}";
}
================================================
FILE: RawInput.Sharp/HidButtonSet.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidButtonSet : IEnumerable<HidButton>
{
internal readonly HidReader reader;
internal readonly HidPButtonCaps buttonCaps;
public int ReportId => buttonCaps.ReportID;
public int ButtonCount => buttonCaps.Range.UsageMax - buttonCaps.Range.UsageMin + 1;
public ushort UsagePage => buttonCaps.UsagePage;
public ushort UsageMin => buttonCaps.Range.UsageMin;
public ushort UsageMax => buttonCaps.Range.UsageMax;
public HidUsageAndPage LinkUsageAndPage => new(buttonCaps.LinkUsagePage, buttonCaps.LinkUsage);
public int LinkCollection => buttonCaps.LinkCollection;
internal HidButtonSet(HidReader reader, HidPButtonCaps buttonCaps)
{
this.reader = reader;
this.buttonCaps = buttonCaps;
}
public HidButtonSetState GetStates(ArraySegment<byte> report) =>
GetStates(report.ToArray(), report.Count);
public HidButtonSetState GetStates(byte[] report, int reportLength) =>
new(this, report, reportLength);
public override string ToString() =>
$"{ReportId}, {LinkCollection}, Link: {{{LinkUsageAndPage}}}, UsagePage: {{{UsagePage}}}, Count: {ButtonCount}";
public IEnumerator<HidButton> GetEnumerator()
{
for (var usage = buttonCaps.Range.UsageMin; usage <= buttonCaps.Range.UsageMax; usage++)
yield return new HidButton(reader, buttonCaps, usage);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
================================================
FILE: RawInput.Sharp/HidButtonSetState.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidButtonSetState : IEnumerable<HidButtonState>
{
readonly byte[] report;
readonly int reportLength;
public HidButtonSet ButtonSet { get; }
public unsafe ushort[] ActiveUsages
{
get
{
fixed (void* preparsedData = ButtonSet.reader.PreparsedData)
return HidP.GetUsages((IntPtr)preparsedData, HidPReportType.Input, ButtonSet.buttonCaps, report, reportLength);
}
}
internal HidButtonSetState(HidButtonSet buttonSet, byte[] report, int reportLength)
{
ButtonSet = buttonSet;
this.report = report;
this.reportLength = reportLength;
}
public override string ToString() =>
$"ButtonSet: {{{ButtonSet}}}, Active: [{string.Join(", ", ActiveUsages)}]";
public IEnumerator<HidButtonState> GetEnumerator()
{
for (var usage = ButtonSet.UsageMin; usage <= ButtonSet.UsageMax; usage++)
yield return new HidButtonState(new HidButton(ButtonSet.reader, ButtonSet.buttonCaps, usage), report, reportLength);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
================================================
FILE: RawInput.Sharp/HidButtonState.cs
================================================
using System;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidButtonState
{
readonly byte[] report;
readonly int reportLength;
public HidButton Button { get; }
public unsafe bool IsActive
{
get
{
fixed (void* preparsedData = Button.reader.PreparsedData)
{
var activeUsages = HidP.GetUsages((IntPtr)preparsedData, HidPReportType.Input, Button.buttonCaps, report, reportLength);
return Array.IndexOf(activeUsages, Button.UsageAndPage.Usage) != -1;
}
}
}
internal HidButtonState(HidButton button, byte[] report, int reportLength)
{
Button = button;
this.report = report;
this.reportLength = reportLength;
}
public override string ToString() =>
$"Button: {{{Button}}}, IsActive: {IsActive}";
}
================================================
FILE: RawInput.Sharp/HidPreparsedByteArrayData.cs
================================================
namespace Linearstar.Windows.RawInput;
public class HidPreparsedByteArrayData : IHidPreparsedData
{
readonly byte[] preparsedData;
public HidPreparsedByteArrayData(byte[] preparsedData) => this.preparsedData = preparsedData;
public ref byte GetPinnableReference() => ref preparsedData[0];
}
================================================
FILE: RawInput.Sharp/HidReader.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidReader
{
readonly HidPCaps capabilities;
public IHidPreparsedData PreparsedData { get; }
public int ValueCount => capabilities.NumberInputValueCaps;
public HidButtonSet[] ButtonSets { get; }
public HidValueSet[] ValueSets { get; }
public unsafe HidReader(IHidPreparsedData preparsedData)
{
fixed (void* preparsedDataPtr = PreparsedData = preparsedData)
{
capabilities = HidP.GetCaps((IntPtr)preparsedDataPtr);
var buttonCaps = HidP.GetButtonCaps((IntPtr)preparsedDataPtr, HidPReportType.Input);
ButtonSets = buttonCaps.Select(i => new HidButtonSet(this, i)).ToArray();
var valueCaps = HidP.GetValueCaps((IntPtr)preparsedDataPtr, HidPReportType.Input);
ValueSets = valueCaps.Select(i => new HidValueSet(this, i)).ToArray();
}
}
}
================================================
FILE: RawInput.Sharp/HidUsageAndPage.cs
================================================
using System;
namespace Linearstar.Windows.RawInput;
public readonly struct HidUsageAndPage : IEquatable<HidUsageAndPage>
{
public static readonly HidUsageAndPage Mouse = new(0x01, 0x02);
public static readonly HidUsageAndPage Joystick = new(0x01, 0x04);
public static readonly HidUsageAndPage GamePad = new(0x01, 0x05);
public static readonly HidUsageAndPage Keyboard = new(0x01, 0x06);
public static readonly HidUsageAndPage Pen = new(0x0D, 0x02);
public static readonly HidUsageAndPage TouchScreen = new(0x0D, 0x04);
public static readonly HidUsageAndPage TouchPad = new(0x0D, 0x05);
public HidUsageAndPage(ushort usagePage, ushort usage)
{
UsagePage = usagePage;
Usage = usage;
}
public ushort Usage
{
get;
}
public ushort UsagePage
{
get;
}
public static bool operator ==(HidUsageAndPage a, HidUsageAndPage b) =>
a.UsagePage == b.UsagePage &&
a.Usage == b.Usage;
public static bool operator !=(HidUsageAndPage a, HidUsageAndPage b) =>
a.UsagePage != b.UsagePage ||
a.Usage != b.Usage;
public bool Equals(HidUsageAndPage other) =>
GetHashCode() == other.GetHashCode();
public override bool Equals(object? obj) =>
obj is HidUsageAndPage huap ? Equals(huap) : base.Equals(obj);
public override int GetHashCode() =>
UsagePage << 16 | Usage;
public override string ToString() =>
$"{UsagePage:X2}:{Usage:X2}";
}
================================================
FILE: RawInput.Sharp/HidValue.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidValue
{
internal readonly HidReader reader;
internal readonly HidPValueCaps valueCaps;
public int ReportId => valueCaps.ReportID;
public int ReportCount => valueCaps.ReportCount;
public HidUsageAndPage UsageAndPage { get; }
public HidUsageAndPage LinkUsageAndPage => new(valueCaps.LinkUsagePage, valueCaps.LinkUsage);
public int LinkCollection => valueCaps.LinkCollection;
public int MinValue => valueCaps.LogicalMin;
public int MaxValue => valueCaps.LogicalMax;
public int MinPhysicalValue => valueCaps.PhysicalMin;
public int MaxPhysicalValue => valueCaps.PhysicalMax;
public bool CanBeNull => valueCaps.HasNull;
internal HidValue(HidReader reader, HidPValueCaps valueCaps, ushort usage)
{
this.reader = reader;
this.valueCaps = valueCaps;
UsageAndPage = new HidUsageAndPage(valueCaps.UsagePage, usage);
}
public HidValueState GetValue(ArraySegment<byte> report) =>
GetValue(report.ToArray(), report.Count);
public HidValueState GetValue(byte[] report, int reportLength) => new(this, report, reportLength);
public override string ToString() =>
$"{ReportId}, {LinkCollection}, Link: {{{LinkUsageAndPage}}}, Usage: {{{UsageAndPage}}}";
}
================================================
FILE: RawInput.Sharp/HidValueSet.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidValueSet : IEnumerable<HidValue>
{
internal readonly HidReader reader;
internal readonly HidPValueCaps valueCaps;
public int ReportId => valueCaps.ReportID;
public int ReportCount => valueCaps.ReportCount;
public int ValueCount => valueCaps.Range.UsageMax - valueCaps.Range.UsageMin + 1;
public ushort UsagePage => valueCaps.UsagePage;
public ushort UsageMin => valueCaps.Range.UsageMin;
public ushort UsageMax => valueCaps.Range.UsageMax;
public HidUsageAndPage LinkUsageAndPage => new(valueCaps.LinkUsagePage, valueCaps.LinkUsage);
public int LinkCollection => valueCaps.LinkCollection;
internal HidValueSet(HidReader reader, HidPValueCaps valueCaps)
{
this.reader = reader;
this.valueCaps = valueCaps;
}
public HidValueSetState GetStates(ArraySegment<byte> report) =>
GetStates(report.ToArray(), report.Count);
public HidValueSetState GetStates(byte[] report, int reportLength) => new(this, report, reportLength);
public override string ToString() =>
$"{ReportId}, {LinkCollection}, Link: {{{LinkUsageAndPage}}}, UsagePage: {{{UsagePage}}}, Count: {ValueCount}";
public IEnumerator<HidValue> GetEnumerator()
{
for (var usage = valueCaps.Range.UsageMin; usage <= valueCaps.Range.UsageMax; usage++)
yield return new HidValue(reader, valueCaps, usage);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
================================================
FILE: RawInput.Sharp/HidValueSetState.cs
================================================
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace Linearstar.Windows.RawInput;
public class HidValueSetState : IEnumerable<HidValueState>
{
readonly byte[] report;
readonly int reportLength;
public HidValueSet ValueSet { get; }
public int[] CurrentValues => this.Select(x => x.CurrentValue).ToArray();
public int?[] ScaledValues => this.Select(x => x.ScaledValue).ToArray();
internal HidValueSetState(HidValueSet valueSet, byte[] report, int reportLength)
{
ValueSet = valueSet;
this.report = report;
this.reportLength = reportLength;
}
public override string ToString() =>
$"ValueSet: {{{ValueSet}}}, CurrentValues: [{string.Join(", ", CurrentValues)}]";
public IEnumerator<HidValueState> GetEnumerator()
{
for (var usage = ValueSet.UsageMin; usage <= ValueSet.UsageMax; usage++)
yield return new HidValueState(new HidValue(ValueSet.reader, ValueSet.valueCaps, usage), report, reportLength);
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
================================================
FILE: RawInput.Sharp/HidValueState.cs
================================================
using System;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class HidValueState
{
readonly byte[] report;
readonly int reportLength;
public HidValue Value { get; }
public unsafe int CurrentValue
{
get
{
fixed (void* preparsedData = Value.reader.PreparsedData)
return HidP.GetUsageValue((IntPtr)preparsedData, HidPReportType.Input, Value.valueCaps, Value.UsageAndPage.Usage, report, reportLength);
}
}
public unsafe int? ScaledValue
{
get
{
fixed (void* preparsedData = Value.reader.PreparsedData)
return HidP.TryGetScaledUsageValue((IntPtr)preparsedData, HidPReportType.Input, Value.valueCaps, Value.UsageAndPage.Usage, report, reportLength, out var value) == NtStatus.Success
? value
: null;
}
}
public bool HasValue
{
get
{
if (!Value.CanBeNull) return true;
var currentValue = CurrentValue;
return currentValue >= Value.MinValue && currentValue <= Value.MaxValue;
}
}
internal HidValueState(HidValue value, byte[] report, int reportLength)
{
Value = value;
this.report = report;
this.reportLength = reportLength;
}
public override string ToString() =>
$"Value: {{{Value}}}, CurrentValue: {CurrentValue}";
}
================================================
FILE: RawInput.Sharp/IHidPreparsedData.cs
================================================
namespace Linearstar.Windows.RawInput;
public interface IHidPreparsedData
{
ref byte GetPinnableReference();
}
================================================
FILE: RawInput.Sharp/MarshalEx.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput;
static class MarshalEx
{
#if NET7_0_OR_GREATER
public static int SizeOf<T>() => Marshal.SizeOf<T>();
#else
public static int SizeOf<T>() => Marshal.SizeOf(typeof(T));
#endif
}
================================================
FILE: RawInput.Sharp/Native/CfgMgr32.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
public static class CfgMgr32
{
[DllImport("cfgmgr32", CharSet = CharSet.Unicode)]
static extern ConfigReturnValue CM_Locate_DevNode(out IntPtr pdnDevInst, string pDeviceID, LocateDevNodeFlags ulFlags);
[DllImport("cfgmgr32", CharSet = CharSet.Unicode)]
static extern ConfigReturnValue CM_Get_DevNode_Property(IntPtr dnDevInst, in DevicePropertyKey propertyKey, out uint propertyType, IntPtr propertyBuffer, ref uint propertyBufferSize, uint ulFlags);
/// <summary>
/// CM_LOCATE_DEVNODE_*
/// </summary>
[Flags]
public enum LocateDevNodeFlags : uint
{
/// <summary>
/// CM_LOCATE_DEVNODE_NORMAL
/// </summary>
Normal = 0x0,
/// <summary>
/// CM_LOCATE_DEVNODE_PHANTOM
/// </summary>
Phantom = 0x1,
/// <summary>
/// CM_LOCATE_DEVNODE_CANCELREMOVE
/// </summary>
CancelRemove = 0x2,
/// <summary>
/// CM_LOCATE_DEVNODE_NOVALIDATION
/// </summary>
NoValidation = 0x4,
}
public static DeviceInstanceHandle LocateDevNode(string devicePath, LocateDevNodeFlags flags)
{
TryLocateDevNode(devicePath, flags, out var device).EnsureSuccess();
return device;
}
public static ConfigReturnValue TryLocateDevNode(string devicePath, LocateDevNodeFlags flags, out DeviceInstanceHandle device)
{
var result = CM_Locate_DevNode(out var devInst, devicePath, flags);
device = result == ConfigReturnValue.Success
? (DeviceInstanceHandle)devInst
: DeviceInstanceHandle.Zero;
return result;
}
public static string? GetDevNodePropertyString(DeviceInstanceHandle device, in DevicePropertyKey propertyKey)
{
TryGetDevNodePropertyString(device, in propertyKey, out var value);
return value;
}
public static ConfigReturnValue TryGetDevNodePropertyString(DeviceInstanceHandle device, in DevicePropertyKey propertyKey, out string? value)
{
var devInst = DeviceInstanceHandle.GetRawValue(device);
uint size = 0;
var result = CM_Get_DevNode_Property(devInst, in propertyKey, out _, IntPtr.Zero, ref size, 0);
if (result != ConfigReturnValue.Success &&
result != ConfigReturnValue.BufferSmall)
{
value = null;
return result;
}
var buffer = Marshal.AllocHGlobal((int)size);
try
{
result = CM_Get_DevNode_Property(devInst, in propertyKey, out _, buffer, ref size, 0);
if (result != ConfigReturnValue.Success)
{
value = null;
return result;
}
value = Marshal.PtrToStringUni(buffer);
return ConfigReturnValue.Success;
}
finally
{
Marshal.FreeHGlobal(buffer);
}
}
static void EnsureSuccess(this ConfigReturnValue result)
{
if (result != ConfigReturnValue.Success) throw new InvalidOperationException(result.ToString());
}
}
================================================
FILE: RawInput.Sharp/Native/ConfigReturnValue.cs
================================================
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// CONFIGRET
/// </summary>
public enum ConfigReturnValue
{
Success = 0x0,
Default = 0x1,
OutOfMemory = 0x2,
InvalidPointer = 0x3,
InvalidFlag = 0x4,
InvalidDevNode = 0x5,
InvalidDevInst = 0x5,
InvalidResDes = 0x6,
InvalidLogConf = 0x7,
InvalidArbitrator = 0x8,
InvalidNodeList = 0x9,
DevNodeHasReqs = 0xA,
DevInstHasReqs = 0xA,
InvalidResourceId = 0xB,
DlvxdNotFound = 0xC,
NoSuchDevNode = 0xD,
NoSuchDevInst = 0xD,
NoMoreLogConf = 0xE,
NoMoreResDes = 0xF,
AlreadySuchDevNode = 0x10,
AlreadySuchDevInst = 0x10,
InvalidRangeList = 0x11,
InvalidRange = 0x12,
Failure = 0x13,
NoSuchLogicalDev = 0x14,
CreateBlocked = 0x15,
NotSystemVm = 0x16,
RemoveVetoed = 0x17,
ApmVetoed = 0x18,
InvalidLoadType = 0x19,
BufferSmall = 0x1A,
NoArbitrator = 0x1B,
NoRegistryHandle = 0x1C,
RegistryError = 0x1D,
InvalidDeviceId = 0x1E,
InvalidData = 0x1F,
InvalidApi = 0x20,
DevloaderNotReady = 0x21,
NeedRestart = 0x22,
NoMoreHwProfiles = 0x23,
DeviceNotThere = 0x24,
NoSuchValue = 0x25,
WrongType = 0x26,
InvalidPriority = 0x27,
NotDisableable = 0x28,
FreeResources = 0x29,
QueryVetoed = 0x2A,
CantShareIrq = 0x2B,
NoDependent = 0x2C,
SameResourecs = 0x2D,
NoSuchRegistryKey = 0x2E,
InvalidMachineName = 0x2F,
RemoteCommFailure = 0x30,
MachineUnavailable = 0x31,
NoCmServices = 0x32,
AccessDenied = 0x33,
CallNotImplemented = 0x34,
InvalidProperty = 0x35,
DeviceInterfaceActive = 0x36,
NoSuchDeviceInterface = 0x37,
InvalidReferenceString = 0x38,
InvalidConflictList = 0x39,
InvalidIndex = 0x3A,
InvalidStructureSize = 0x3B,
}
================================================
FILE: RawInput.Sharp/Native/DeviceInstanceHandle.cs
================================================
using System;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// DEVINST
/// </summary>
public readonly struct DeviceInstanceHandle : IEquatable<DeviceInstanceHandle>
{
readonly IntPtr value;
public static DeviceInstanceHandle Zero => (DeviceInstanceHandle)IntPtr.Zero;
DeviceInstanceHandle(IntPtr value) => this.value = value;
public static IntPtr GetRawValue(DeviceInstanceHandle handle) => handle.value;
public static explicit operator DeviceInstanceHandle(IntPtr value) => new(value);
public static bool operator ==(DeviceInstanceHandle a, DeviceInstanceHandle b) => a.Equals(b);
public static bool operator !=(DeviceInstanceHandle a, DeviceInstanceHandle b) => !a.Equals(b);
public bool Equals(DeviceInstanceHandle other) => value.Equals(other.value);
public override bool Equals(object? obj) =>
obj is DeviceInstanceHandle other &&
Equals(other);
public override int GetHashCode() => value.GetHashCode();
public override string ToString() => value.ToString();
}
================================================
FILE: RawInput.Sharp/Native/DevicePropertyKey.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// DEVPROPKEY
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct DevicePropertyKey
{
/// <summary>
/// DEVPKEY_NAME
/// </summary>
public static readonly DevicePropertyKey Name = new(0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac, 10);
/// <summary>
/// DEVPKEY_Device_Manufacturer
/// </summary>
public static readonly DevicePropertyKey DeviceManufacturer = new(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13);
/// <summary>
/// DEVPKEY_Device_FriendlyName
/// </summary>
public static readonly DevicePropertyKey DeviceFriendlyName = new(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
readonly Guid fmtid;
readonly int pid;
public DevicePropertyKey(uint l, ushort w1, ushort w2, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, int pid)
{
fmtid = new Guid((int)l, (short)w1, (short)w2, b1, b2, b3, b4, b5, b6, b7, b8);
this.pid = pid;
}
}
================================================
FILE: RawInput.Sharp/Native/HidD.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Linearstar.Windows.RawInput.Native;
public static class HidD
{
[DllImport("hid", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool HidD_GetManufacturerString(IntPtr HidDeviceObject, [Out] byte[] Buffer, uint BufferLength);
[DllImport("hid", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool HidD_GetProductString(IntPtr HidDeviceObject, [Out] byte[] Buffer, uint BufferLength);
[DllImport("hid", CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool HidD_GetSerialNumberString(IntPtr HidDeviceObject, [Out] byte[] Buffer, uint BufferLength);
[DllImport("hid")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool HidD_GetPreparsedData(IntPtr HidDeviceObject, out IntPtr PreparsedData);
[DllImport("hid")]
[return: MarshalAs(UnmanagedType.U1)]
static extern bool HidD_FreePreparsedData(IntPtr PreparsedData);
public static HidDeviceHandle OpenDevice(string devicePath)
{
var deviceHandle = Kernel32.CreateFile(devicePath, Kernel32.ShareMode.Read | Kernel32.ShareMode.Write, Kernel32.CreateDisposition.OpenExisting);
return (HidDeviceHandle)deviceHandle;
}
public static bool TryOpenDevice(string devicePath, out HidDeviceHandle device)
{
if (!Kernel32.TryCreateFile(
devicePath,
Kernel32.ShareMode.Read | Kernel32.ShareMode.Write,
Kernel32.CreateDisposition.OpenExisting,
out var deviceHandle))
{
device = HidDeviceHandle.Zero;
return false;
}
device = (HidDeviceHandle)deviceHandle;
return true;
}
public static void CloseDevice(HidDeviceHandle device)
{
var deviceHandle = HidDeviceHandle.GetRawValue(device);
Kernel32.CloseHandle(deviceHandle);
}
public static string? GetManufacturerString(HidDeviceHandle device)
{
var deviceHandle = HidDeviceHandle.GetRawValue(device);
return GetString(deviceHandle, HidD_GetManufacturerString);
}
public static string? GetProductString(HidDeviceHandle device)
{
var deviceHandle = HidDeviceHandle.GetRawValue(device);
return GetString(deviceHandle, HidD_GetProductString);
}
public static string? GetSerialNumberString(HidDeviceHandle device)
{
var deviceHandle = HidDeviceHandle.GetRawValue(device);
return GetString(deviceHandle, HidD_GetSerialNumberString);
}
public static HidPreparsedData GetPreparsedData(HidDeviceHandle device)
{
var deviceHandle = HidDeviceHandle.GetRawValue(device);
HidD_GetPreparsedData(deviceHandle, out var preparsedData);
return (HidPreparsedData)preparsedData;
}
public static void FreePreparsedData(HidPreparsedData preparsedData)
{
HidD_FreePreparsedData((IntPtr)preparsedData);
}
static string? GetString(IntPtr handle, Func<IntPtr, byte[], uint, bool> proc)
{
var buf = new byte[256];
if (!proc(handle, buf, (uint)buf.Length))
return null;
var str = Encoding.Unicode.GetString(buf, 0, buf.Length);
return str.Contains("\0") ? str.Substring(0, str.IndexOf('\0')) : str;
}
}
================================================
FILE: RawInput.Sharp/Native/HidDeviceHandle.cs
================================================
using System;
namespace Linearstar.Windows.RawInput.Native;
public readonly struct HidDeviceHandle : IEquatable<HidDeviceHandle>
{
readonly IntPtr value;
public static HidDeviceHandle Zero => (HidDeviceHandle)IntPtr.Zero;
HidDeviceHandle(IntPtr value) => this.value = value;
public static IntPtr GetRawValue(HidDeviceHandle handle) => handle.value;
public static explicit operator HidDeviceHandle(IntPtr value) => new(value);
public static bool operator ==(HidDeviceHandle a, HidDeviceHandle b) => a.Equals(b);
public static bool operator !=(HidDeviceHandle a, HidDeviceHandle b) => !a.Equals(b);
public bool Equals(HidDeviceHandle other) => value.Equals(other.value);
public override bool Equals(object? obj) =>
obj is HidDeviceHandle other &&
Equals(other);
public override int GetHashCode() => value.GetHashCode();
public override string ToString() => value.ToString();
}
================================================
FILE: RawInput.Sharp/Native/HidP.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
public static class HidP
{
[DllImport("hid")]
static extern NtStatus HidP_GetCaps(IntPtr preparsedData, out HidPCaps capabilities);
[DllImport("hid")]
static extern NtStatus HidP_GetButtonCaps(HidPReportType reportType, [Out] HidPButtonCaps[] buttonCaps, ref ushort buttonCapsLength, IntPtr preparsedData);
[DllImport("hid")]
static extern NtStatus HidP_GetValueCaps(HidPReportType reportType, [Out] HidPValueCaps[] valueCaps, ref ushort valueCapsLength, IntPtr preparsedData);
[DllImport("hid")]
static extern NtStatus HidP_GetUsages(HidPReportType reportType, ushort usagePage, ushort linkCollection, [Out] ushort[]? usageList, ref uint usageLength, IntPtr preparsedData, byte[] report, uint reportLength);
[DllImport("hid")]
static extern NtStatus HidP_GetUsageValue(HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, out int usageValue, IntPtr preparsedData, byte[] report, uint reportLength);
[DllImport("hid")]
static extern NtStatus HidP_GetScaledUsageValue(HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, out int usageValue, IntPtr preparsedData, byte[] report, uint reportLength);
[DllImport("hid")]
static extern NtStatus HidP_GetUsageValueArray(HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, [Out] byte[] usageValue, ushort usageValueByteLength, IntPtr preparsedData, byte[] report, uint reportLength);
public static NtStatus TryGetCaps(IntPtr preparsedData, out HidPCaps capabilities) =>
HidP_GetCaps(preparsedData, out capabilities);
public static NtStatus TryGetCaps(HidPreparsedData preparsedData, out HidPCaps capabilities) =>
TryGetCaps((IntPtr)preparsedData, out capabilities);
public static HidPCaps GetCaps(IntPtr preparsedData)
{
TryGetCaps(preparsedData, out var capabilities).EnsureSuccess();
return capabilities;
}
public static HidPCaps GetCaps(HidPreparsedData preparsedData) =>
GetCaps((IntPtr)preparsedData);
public static NtStatus TryGetButtonCaps(IntPtr preparsedData, HidPReportType reportType, out HidPButtonCaps[] buttonCaps)
{
var caps = GetCaps(preparsedData);
var capsCount = reportType switch
{
HidPReportType.Input => caps.NumberInputButtonCaps,
HidPReportType.Output => caps.NumberOutputButtonCaps,
HidPReportType.Feature => caps.NumberFeatureButtonCaps,
_ => throw new ArgumentException($"Invalid HidPReportType: {reportType}", nameof(reportType)),
};
buttonCaps = new HidPButtonCaps[capsCount];
return HidP_GetButtonCaps(reportType, buttonCaps, ref capsCount, preparsedData);
}
public static NtStatus TryGetButtonCaps(HidPreparsedData preparsedData, HidPReportType reportType, out HidPButtonCaps[] buttonCaps) =>
TryGetButtonCaps((IntPtr)preparsedData, reportType, out buttonCaps);
public static HidPButtonCaps[] GetButtonCaps(IntPtr preparsedData, HidPReportType reportType)
{
TryGetButtonCaps(preparsedData, reportType, out var buttonCaps).EnsureSuccess();
return buttonCaps;
}
public static HidPButtonCaps[] GetButtonCaps(HidPreparsedData preparsedData, HidPReportType reportType) =>
GetButtonCaps((IntPtr)preparsedData, reportType);
public static NtStatus TryGetValueCaps(IntPtr preparsedData, HidPReportType reportType, out HidPValueCaps[] valueCaps)
{
var caps = GetCaps(preparsedData);
var capsCount = reportType switch
{
HidPReportType.Input => caps.NumberInputValueCaps,
HidPReportType.Output => caps.NumberOutputValueCaps,
HidPReportType.Feature => caps.NumberFeatureValueCaps,
_ => throw new ArgumentException($"Invalid HidPReportType: {reportType}", nameof(reportType)),
};
valueCaps = new HidPValueCaps[capsCount];
return HidP_GetValueCaps(reportType, valueCaps, ref capsCount, preparsedData);
}
public static NtStatus TryGetValueCaps(HidPreparsedData preparsedData, HidPReportType reportType, out HidPValueCaps[] valueCaps) =>
TryGetValueCaps((IntPtr)preparsedData, reportType, out valueCaps);
public static HidPValueCaps[] GetValueCaps(IntPtr preparsedData, HidPReportType reportType)
{
TryGetValueCaps(preparsedData, reportType, out var valueCaps).EnsureSuccess();
return valueCaps;
}
public static HidPValueCaps[] GetValueCaps(HidPreparsedData preparsedData, HidPReportType reportType) =>
GetValueCaps((IntPtr)preparsedData, reportType);
public static NtStatus TryGetUsages(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, byte[] report, int reportLength, out ushort[] usageList)
{
uint usageCount = 0;
HidP_GetUsages(reportType, usagePage, linkCollection, null, ref usageCount, preparsedData, report, (uint)reportLength);
usageList = new ushort[usageCount];
return HidP_GetUsages(reportType, usagePage, linkCollection, usageList, ref usageCount, preparsedData, report, (uint)reportLength);
}
public static NtStatus TryGetUsages(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, byte[] report, int reportLength, out ushort[] usageList) =>
TryGetUsages((IntPtr)preparsedData, reportType, usagePage, linkCollection, report, reportLength, out usageList);
public static NtStatus TryGetUsages(IntPtr preparsedData, HidPReportType reportType, HidPButtonCaps buttonCaps, byte[] report, int reportLength, out ushort[] usageList) =>
TryGetUsages(preparsedData, reportType, buttonCaps.UsagePage, buttonCaps.LinkCollection, report, reportLength, out usageList);
public static NtStatus TryGetUsages(HidPreparsedData preparsedData, HidPReportType reportType, HidPButtonCaps buttonCaps, byte[] report, int reportLength, out ushort[] usageList) =>
TryGetUsages(preparsedData, reportType, buttonCaps.UsagePage, buttonCaps.LinkCollection, report, reportLength, out usageList);
public static ushort[] GetUsages(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, byte[] report, int reportLength)
{
TryGetUsages(preparsedData, reportType, usagePage, linkCollection, report, reportLength, out var usageList).EnsureSuccess();
return usageList;
}
public static ushort[] GetUsages(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, byte[] report, int reportLength) =>
GetUsages((IntPtr)preparsedData, reportType, usagePage, linkCollection, report, reportLength);
public static ushort[] GetUsages(IntPtr preparsedData, HidPReportType reportType, HidPButtonCaps buttonCaps, byte[] report, int reportLength) =>
GetUsages(preparsedData, reportType, buttonCaps.UsagePage, buttonCaps.LinkCollection, report, reportLength);
public static ushort[] GetUsages(HidPreparsedData preparsedData, HidPReportType reportType, HidPButtonCaps buttonCaps, byte[] report, int reportLength) =>
GetUsages(preparsedData, reportType, buttonCaps.UsagePage, buttonCaps.LinkCollection, report, reportLength);
public static NtStatus TryGetUsageValue(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength, out int usageValue) =>
HidP_GetUsageValue(reportType, usagePage, linkCollection, usage, out usageValue, preparsedData, report, (uint)reportLength);
public static NtStatus TryGetUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetUsageValue((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength, out usageValue);
public static NtStatus TryGetUsageValue(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength, out usageValue);
public static NtStatus TryGetUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength, out usageValue);
public static int GetUsageValue(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength)
{
TryGetUsageValue(preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength, out var usageValue).EnsureSuccess();
return usageValue;
}
public static int GetUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength) =>
GetUsageValue((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength);
public static int GetUsageValue(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength);
public static int GetUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength);
public static NtStatus TryGetScaledUsageValue(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength, out int usageValue) =>
HidP_GetScaledUsageValue(reportType, usagePage, linkCollection, usage, out usageValue, preparsedData, report, (uint)reportLength);
public static NtStatus TryGetScaledUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetScaledUsageValue((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength, out usageValue);
public static NtStatus TryGetScaledUsageValue(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetScaledUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength, out usageValue);
public static NtStatus TryGetScaledUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out int usageValue) =>
TryGetScaledUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength, out usageValue);
public static int GetScaledUsageValue(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength)
{
TryGetScaledUsageValue(preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength, out var usageValue).EnsureSuccess();
return usageValue;
}
public static int GetScaledUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, byte[] report, int reportLength) =>
GetScaledUsageValue((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, report, reportLength);
public static int GetScaledUsageValue(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetScaledUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength);
public static int GetScaledUsageValue(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetScaledUsageValue(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, report, reportLength);
public static NtStatus TryGetUsageValueArray(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, ushort usageValueByteLength, byte[] report, int reportLength, out byte[] usageValue)
{
usageValue = new byte[usageValueByteLength];
return HidP_GetUsageValueArray(reportType, usagePage, linkCollection, usage, usageValue, usageValueByteLength, preparsedData, report, (uint)reportLength);
}
public static NtStatus TryGetUsageValueArray(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, ushort usageValueByteLength, byte[] report, int reportLength, out byte[] usageValue) =>
TryGetUsageValueArray((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, usageValueByteLength, report, reportLength, out usageValue);
public static NtStatus TryGetUsageValueArray(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out byte[] usageValue) =>
TryGetUsageValueArray(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, (ushort)(valueCaps.BitSize * valueCaps.ReportCount), report, reportLength, out usageValue);
public static NtStatus TryGetUsageValueArray(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength, out byte[] usageValue) =>
TryGetUsageValueArray(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, (ushort)(valueCaps.BitSize * valueCaps.ReportCount), report, reportLength, out usageValue);
public static byte[] GetUsageValueArray(IntPtr preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, ushort usageValueByteLength, byte[] report, int reportLength)
{
TryGetUsageValueArray(preparsedData, reportType, usagePage, linkCollection, usage, usageValueByteLength, report, reportLength, out var usageValue).EnsureSuccess();
return usageValue;
}
public static byte[] GetUsageValueArray(HidPreparsedData preparsedData, HidPReportType reportType, ushort usagePage, ushort linkCollection, ushort usage, ushort usageValueByteLength, byte[] report, int reportLength) =>
GetUsageValueArray((IntPtr)preparsedData, reportType, usagePage, linkCollection, usage, usageValueByteLength, report, reportLength);
public static byte[] GetUsageValueArray(IntPtr preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetUsageValueArray(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, (ushort)(valueCaps.BitSize * valueCaps.ReportCount), report, reportLength);
public static byte[] GetUsageValueArray(HidPreparsedData preparsedData, HidPReportType reportType, HidPValueCaps valueCaps, ushort usage, byte[] report, int reportLength) =>
GetUsageValueArray(preparsedData, reportType, valueCaps.UsagePage, valueCaps.LinkCollection, usage, (ushort)(valueCaps.BitSize * valueCaps.ReportCount), report, reportLength);
public static void EnsureSuccess(this NtStatus result)
{
if (result != NtStatus.Success) throw new InvalidOperationException(result.ToString());
}
}
================================================
FILE: RawInput.Sharp/Native/HidPButtonCaps.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HIDP_BUTTON_CAPS
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct HidPButtonCaps
{
[FieldOffset(0)]
public ushort UsagePage;
[FieldOffset(2)]
public byte ReportID;
[FieldOffset(3), MarshalAs(UnmanagedType.U1)]
public bool IsAlias;
[FieldOffset(4)]
public ushort BitField;
[FieldOffset(6)]
public ushort LinkCollection;
[FieldOffset(8)]
public ushort LinkUsage;
[FieldOffset(10)]
public ushort LinkUsagePage;
[FieldOffset(12), MarshalAs(UnmanagedType.U1)]
public bool IsRange;
[FieldOffset(13), MarshalAs(UnmanagedType.U1)]
public bool IsStringRange;
[FieldOffset(14), MarshalAs(UnmanagedType.U1)]
public bool IsDesignatorRange;
[FieldOffset(15), MarshalAs(UnmanagedType.U1)]
public bool IsAbsolute;
[FieldOffset(16), MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
readonly int[] Reserved;
[FieldOffset(56)]
public HidPCapsRange Range;
[FieldOffset(56)]
public HidPCapsNotRange NotRange;
}
================================================
FILE: RawInput.Sharp/Native/HidPCaps.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HIDP_CAPS
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct HidPCaps
{
readonly ushort Usage;
readonly ushort UsagePage;
public ushort InputReportByteLength;
public ushort OutputReportByteLength;
public ushort FeatureReportByteLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
readonly ushort[] reserved;
public ushort NumberLinkCollectionNodes;
public ushort NumberInputButtonCaps;
public ushort NumberInputValueCaps;
public ushort NumberInputDataIndices;
public ushort NumberOutputButtonCaps;
public ushort NumberOutputValueCaps;
public ushort NumberOutputDataIndices;
public ushort NumberFeatureButtonCaps;
public ushort NumberFeatureValueCaps;
public ushort NumberFeatureDateIndices;
public HidUsageAndPage UsageAndPage => new(UsagePage, Usage);
}
================================================
FILE: RawInput.Sharp/Native/HidPCapsNotRange.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
[StructLayout(LayoutKind.Sequential)]
public struct HidPCapsNotRange
{
public ushort Usage;
readonly ushort Reserved1;
public ushort StringIndex;
readonly ushort Reserved2;
public ushort DesignatorIndex;
readonly ushort Reserved3;
public ushort DataIndex;
readonly ushort Reserved4;
}
================================================
FILE: RawInput.Sharp/Native/HidPCapsRange.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
[StructLayout(LayoutKind.Sequential)]
public struct HidPCapsRange
{
public ushort UsageMin;
public ushort UsageMax;
public ushort StringMin;
public ushort StringMax;
public ushort DesignatorMin;
public ushort DesignatorMax;
public ushort DataIndexMin;
public ushort DataIndexMax;
}
================================================
FILE: RawInput.Sharp/Native/HidPReportType.cs
================================================
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HIDP_REPORT_TYPE
/// </summary>
public enum HidPReportType
{
Input = 0,
Output = 1,
Feature = 2,
}
================================================
FILE: RawInput.Sharp/Native/HidPValueCaps.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HIDP_VALUE_CAPS
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct HidPValueCaps
{
[FieldOffset(0)]
public ushort UsagePage;
[FieldOffset(2)]
public byte ReportID;
[FieldOffset(3), MarshalAs(UnmanagedType.U1)]
public bool IsAlias;
[FieldOffset(4)]
public ushort BitField;
[FieldOffset(6)]
public ushort LinkCollection;
[FieldOffset(8)]
public ushort LinkUsage;
[FieldOffset(10)]
public ushort LinkUsagePage;
[FieldOffset(12), MarshalAs(UnmanagedType.U1)]
public bool IsRange;
[FieldOffset(13), MarshalAs(UnmanagedType.U1)]
public bool IsStringRange;
[FieldOffset(14), MarshalAs(UnmanagedType.U1)]
public bool IsDesignatorRange;
[FieldOffset(15), MarshalAs(UnmanagedType.U1)]
public bool IsAbsolute;
[FieldOffset(16), MarshalAs(UnmanagedType.U1)]
public bool HasNull;
[FieldOffset(18)]
public ushort BitSize;
[FieldOffset(20)]
public ushort ReportCount;
[FieldOffset(32)]
public uint UnitsExp;
[FieldOffset(36)]
public uint Units;
[FieldOffset(40)]
public int LogicalMin;
[FieldOffset(44)]
public int LogicalMax;
[FieldOffset(48)]
public int PhysicalMin;
[FieldOffset(52)]
public int PhysicalMax;
[FieldOffset(56)]
public HidPCapsRange Range;
[FieldOffset(56)]
public HidPCapsNotRange NotRange;
}
================================================
FILE: RawInput.Sharp/Native/HidPreparsedData.cs
================================================
using System;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HIDP_PREPARSED_DATA
/// </summary>
public readonly struct HidPreparsedData : IHidPreparsedData, IEquatable<HidPreparsedData>
{
readonly IntPtr value;
public static HidPreparsedData Zero => (HidPreparsedData)IntPtr.Zero;
HidPreparsedData(IntPtr value)
{
this.value = value;
}
public static explicit operator HidPreparsedData(IntPtr value) => new(value);
public static explicit operator IntPtr(HidPreparsedData preparsedData) => preparsedData.value;
public static bool operator ==(HidPreparsedData a, HidPreparsedData b) => a.Equals(b);
public static bool operator !=(HidPreparsedData a, HidPreparsedData b) => !a.Equals(b);
public bool Equals(HidPreparsedData other) => value.Equals(other.value);
public override bool Equals(object? obj) =>
obj is HidPreparsedData other &&
Equals(other);
public override int GetHashCode() => value.GetHashCode();
public override string ToString() => value.ToString();
public unsafe ref byte GetPinnableReference() => ref *(byte*)value.ToPointer();
}
================================================
FILE: RawInput.Sharp/Native/Kernel32.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Linearstar.Windows.RawInput.Native;
static class Kernel32
{
[DllImport("kernel32", EntryPoint = "CreateFile", SetLastError = true, CharSet = CharSet.Unicode)]
static extern IntPtr CreateFileCore(string lpFileName, DesiredAccess dwDesiredAccess, ShareMode dwShareMode, IntPtr lpSecurityAttributes, CreateDisposition dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32", EntryPoint = "GetModuleHandle", SetLastError = true)]
static extern IntPtr GetModuleHandleCore(string lpModuleName);
[DllImport("kernel32", EntryPoint = "GetProcAddress", SetLastError = true)]
static extern IntPtr GetProcAddressCore(IntPtr hModule, string procName);
[DllImport("kernel32", EntryPoint = "IsWow64Process", SetLastError = true)]
static extern bool IsWow64ProcessCore(IntPtr hProcess, out bool lpSystemInfo);
[DllImport("kernel32")]
public static extern IntPtr GetCurrentProcess();
[DllImport("kernel32", SetLastError = true)]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr Arguments);
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
[Flags]
public enum DesiredAccess : uint
{
None,
Write = 0x40000000,
Read = 0x80000000
}
[Flags]
public enum ShareMode : uint
{
None,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004
}
public enum CreateDisposition : uint
{
CreateNew = 1,
CreateAlways,
OpenExisting,
OpenAlways,
TruncateExisting
}
public static IntPtr GetModuleHandle(string moduleName)
{
var hModule = GetModuleHandleCore(moduleName);
if (hModule == IntPtr.Zero) throw new Win32ErrorException();
return hModule;
}
public static IntPtr GetProcAddress(IntPtr hModule, string procName)
{
var farProc = GetProcAddressCore(hModule, procName);
if (farProc == IntPtr.Zero) throw new Win32ErrorException();
return farProc;
}
public static bool IsWow64Process(IntPtr hProcess)
{
if (!IsWow64ProcessCore(hProcess, out var result)) throw new Win32ErrorException();
return result;
}
public static IntPtr CreateFile(
string fileName,
ShareMode shareMode,
CreateDisposition creationDisposition,
DesiredAccess desiredAccess = DesiredAccess.None,
IntPtr securityAttributes = default,
uint flagsAndAttributes = 0,
IntPtr templateFile = default)
{
var handle = CreateFileCore(fileName, desiredAccess, shareMode, securityAttributes, creationDisposition, flagsAndAttributes, templateFile);
if (handle == new IntPtr(-1)) throw new Win32ErrorException();
return handle;
}
public static bool TryCreateFile(
string fileName,
ShareMode shareMode,
CreateDisposition creationDisposition,
out IntPtr handle,
DesiredAccess desiredAccess = DesiredAccess.None,
IntPtr securityAttributes = default,
uint flagsAndAttributes = 0,
IntPtr templateFile = default)
{
handle = CreateFileCore(fileName, desiredAccess, shareMode, securityAttributes, creationDisposition, flagsAndAttributes, templateFile);
return handle != new IntPtr(-1);
}
public static string FormatMessage(int errorCode)
{
var message = new StringBuilder(255);
var charsWritten = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, IntPtr.Zero, (uint)errorCode, 0, message, message.Capacity, IntPtr.Zero);
if (charsWritten == 0) throw new Win32ErrorException();
return message.ToString();
}
}
================================================
FILE: RawInput.Sharp/Native/NtStatus.cs
================================================
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// NTSTATUS
/// </summary>
public enum NtStatus : uint
{
Success = 0x00110000,
Null = 0x80110001,
InvalidPreparsedData = 0xC0110001,
InvalidReportType = 0xC0110002,
InvalidReportLength = 0xC0110003,
UsageNotFound = 0xC0110004,
ValueOutOfRange = 0xC0110005,
BadLogPhyValues = 0xC0110006,
BufferTooSmall = 0xC0110007,
InternalError = 0xC0110008,
I8042TransUnknown = 0xC0110009,
IncompatibleReportId = 0xC011000A,
NotValueArray = 0xC011000B,
IsValueArray = 0xC011000C,
DataIndexNotFound = 0xC011000D,
DataIndexOutOfRange = 0xC011000E,
ButtonNotPressed = 0xC011000F,
ReportDoesNotExist = 0xC0110010,
NotImplemented = 0xC0110020,
}
================================================
FILE: RawInput.Sharp/Native/RawHid.cs
================================================
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RAWHID
/// </summary>
public struct RawHid
{
int dwSizeHid;
int dwCount;
byte[] rawData;
public int ElementSize => dwSizeHid;
public int Count => dwCount;
public unsafe byte[] RawData => rawData;
public static unsafe RawHid FromPointer(void* ptr)
{
var result = new RawHid();
var intPtr = (int*)ptr;
result.dwSizeHid = intPtr[0];
result.dwCount = intPtr[1];
result.rawData = new byte[result.ElementSize * result.Count];
Marshal.Copy(new IntPtr(&intPtr[2]), result.rawData, 0, result.rawData.Length);
return result;
}
public ArraySegment<byte>[] ToHidReports()
{
var elementSize = ElementSize;
var rawDataArray = RawData;
return Enumerable.Range(0, Count)
.Select(x => new ArraySegment<byte>(rawDataArray, elementSize * x, elementSize))
.ToArray();
}
public unsafe byte[] ToStructure()
{
var result = new byte[dwSizeHid * dwCount + sizeof(int) * 2];
fixed (byte* resultPtr = result)
{
var intPtr = (int*)resultPtr;
intPtr[0] = dwSizeHid;
intPtr[1] = dwCount;
}
rawData.CopyTo(result, sizeof(int) * 2);
return result;
}
public override string ToString() =>
$"{{Count: {Count}, Size: {ElementSize}, Content: {BitConverter.ToString(RawData).Replace("-", " ")}}}";
}
================================================
FILE: RawInput.Sharp/Native/RawInputDeviceHandle.cs
================================================
using System;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HANDLE
/// </summary>
public readonly struct RawInputDeviceHandle : IEquatable<RawInputDeviceHandle>
{
readonly IntPtr value;
public static RawInputDeviceHandle Zero => (RawInputDeviceHandle)IntPtr.Zero;
RawInputDeviceHandle(IntPtr value) => this.value = value;
public static IntPtr GetRawValue(RawInputDeviceHandle handle) => handle.value;
public static explicit operator RawInputDeviceHandle(IntPtr value) => new(value);
public static bool operator ==(RawInputDeviceHandle a, RawInputDeviceHandle b) => a.Equals(b);
public static bool operator !=(RawInputDeviceHandle a, RawInputDeviceHandle b) => !a.Equals(b);
public bool Equals(RawInputDeviceHandle other) => value.Equals(other.value);
public override bool Equals(object? obj) =>
obj is RawInputDeviceHandle other &&
Equals(other);
public override int GetHashCode() => value.GetHashCode();
public override string ToString() => value.ToString();
}
================================================
FILE: RawInput.Sharp/Native/RawInputDeviceInfo.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RID_DEVICE_INFO
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public readonly struct RawInputDeviceInfo
{
[FieldOffset(0)]
readonly int sbSize;
[FieldOffset(4)]
readonly RawInputDeviceType dwType;
[FieldOffset(8)]
readonly RawInputMouseInfo mouse;
[FieldOffset(8)]
readonly RawInputKeyboardInfo keyboard;
[FieldOffset(8)]
readonly RawInputHidInfo hid;
/// <summary>
/// dwType
/// </summary>
public RawInputDeviceType Type => dwType;
/// <summary>
/// mouse
/// </summary>
public RawInputMouseInfo Mouse => mouse;
/// <summary>
/// keyboard
/// </summary>
public RawInputKeyboardInfo Keyboard => keyboard;
/// <summary>
/// hid
/// </summary>
public RawInputHidInfo Hid => hid;
}
================================================
FILE: RawInput.Sharp/Native/RawInputDeviceInfoBehavior.cs
================================================
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RIDI_*
/// </summary>
public enum RawInputDeviceInfoBehavior : uint
{
/// <summary>
/// RIDI_PREPARSEDDATA
/// </summary>
PreparsedData = 0x20000005,
/// <summary>
/// RIDI_DEVICENAME
/// </summary>
DeviceName = 0x20000007,
/// <summary>
/// RIDI_DEVICEINFO
/// </summary>
DeviceInfo = 0x2000000b,
}
================================================
FILE: RawInput.Sharp/Native/RawInputDeviceListItem.cs
================================================
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RAWINPUTDEVICELIST
/// </summary>
public struct RawInputDeviceListItem
{
/// <summary>
/// hDevice
/// </summary>
public RawInputDeviceHandle Device { get; set; }
/// <summary>
/// dwType
/// </summary>
public RawInputDeviceType Type { get; set; }
}
================================================
FILE: RawInput.Sharp/Native/RawInputHandle.cs
================================================
using System;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// HRAWINPUT
/// </summary>
public readonly struct RawInputHandle : IEquatable<RawInputHandle>
{
readonly IntPtr value;
public static RawInputHandle Zero => (RawInputHandle)IntPtr.Zero;
RawInputHandle(IntPtr value) => this.value = value;
public static IntPtr GetRawValue(RawInputHandle handle) => handle.value;
public static explicit operator RawInputHandle(IntPtr value) => new(value);
public static bool operator ==(RawInputHandle a, RawInputHandle b) => a.Equals(b);
public static bool operator !=(RawInputHandle a, RawInputHandle b) => !a.Equals(b);
public bool Equals(RawInputHandle other) => value.Equals(other.value);
public override bool Equals(object? obj) =>
obj is RawInputHandle other &&
Equals(other);
public override int GetHashCode() => value.GetHashCode();
public override string ToString() => value.ToString();
}
================================================
FILE: RawInput.Sharp/Native/RawInputHeader.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RAWINPUTHEADER
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawInputHeader
{
readonly RawInputDeviceType dwType;
readonly int dwSize;
readonly RawInputDeviceHandle hDevice;
readonly IntPtr wParam;
public RawInputDeviceType Type => dwType;
public int Size => dwSize;
public RawInputDeviceHandle DeviceHandle => hDevice;
public IntPtr WParam => wParam;
public override string ToString() =>
$"{{{Type}: {DeviceHandle}, WParam: {WParam}}}";
}
================================================
FILE: RawInput.Sharp/Native/RawInputHidInfo.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RID_DEVICE_INFO_HID
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawInputHidInfo
{
readonly int dwVendorId;
readonly int dwProductId;
readonly int dwVersionNumber;
readonly ushort usUsagePage;
readonly ushort usUsage;
/// <summary>
/// dwVendorId
/// </summary>
public int VendorId => dwVendorId;
/// <summary>
/// dwProductId
/// </summary>
public int ProductId => dwProductId;
/// <summary>
/// dwVersionNumber
/// </summary>
public int VersionNumber => dwVersionNumber;
/// <summary>
/// usUsagePage, usUsage
/// </summary>
public HidUsageAndPage UsageAndPage => new(usUsagePage, usUsage);
}
================================================
FILE: RawInput.Sharp/Native/RawInputKeyboardInfo.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RID_DEVICE_INFO_KEYBOARD
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawInputKeyboardInfo
{
readonly int dwType;
readonly int dwSubType;
readonly int dwKeyboardMode;
readonly int dwNumberOfFunctionKeys;
readonly int dwNumberOfIndicators;
readonly int dwNumberOfKeysTotal;
/// <summary>
/// dwType
/// </summary>
public int KeyboardType => dwType;
/// <summary>
/// dwSubType
/// </summary>
public int KeyboardSubType => dwSubType;
/// <summary>
/// dwKeyboardMode
/// </summary>
public int KeyboardMode => dwKeyboardMode;
/// <summary>
/// dwNumberOfFunctionKeys
/// </summary>
public int FunctionKeyCount => dwNumberOfFunctionKeys;
/// <summary>
/// dwNumberOfIndicators
/// </summary>
public int IndicatorCount => dwNumberOfIndicators;
/// <summary>
/// dwNumberOfKeysTotal
/// </summary>
public int TotalKeyCount => dwNumberOfKeysTotal;
}
================================================
FILE: RawInput.Sharp/Native/RawInputMouseInfo.cs
================================================
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RID_DEVICE_INFO_MOUSE
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawInputMouseInfo
{
readonly int dwId;
readonly int dwNumberOfButtons;
readonly int dwSampleRate;
[MarshalAs(UnmanagedType.Bool)]
readonly bool fHasHorizontalWheel;
/// <summary>
/// dwId
/// </summary>
public int Id => dwId;
/// <summary>
/// dwNumberOfButtons
/// </summary>
public int ButtonCount => dwNumberOfButtons;
/// <summary>
/// dwSampleRate
/// </summary>
public int SampleRate => dwSampleRate;
/// <summary>
/// fHasHorizontalWheel
/// </summary>
public bool HasHorizontalWheel => fHasHorizontalWheel;
}
================================================
FILE: RawInput.Sharp/Native/RawKeyboard.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RAWKEYBOARD
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawKeyboard
{
readonly ushort usMakeCode;
readonly RawKeyboardFlags usFlags;
readonly ushort usReserverd;
readonly ushort usVKey;
readonly uint ulMessage;
readonly uint ulExtraInformation;
public int ScanCode => usMakeCode;
public RawKeyboardFlags Flags => usFlags;
public int VirutalKey => usVKey;
public uint WindowMessage => ulMessage;
public uint ExtraInformation => ulExtraInformation;
public override string ToString() =>
$"{{Key: {VirutalKey}, ScanCode: {ScanCode}, Flags: {Flags}}}";
}
/// <summary>
/// RI_KEY_*
/// </summary>
[Flags]
public enum RawKeyboardFlags : ushort
{
/// <summary>
/// RI_KEY_MAKE
/// </summary>
None = 0,
/// <summary>
/// RI_KEY_BREAK
/// </summary>
Up = 1,
/// <summary>
/// RI_KEY_E0
/// </summary>
KeyE0 = 2,
/// <summary>
/// RI_KEY_E1
/// </summary>
KeyE1 = 4,
}
================================================
FILE: RawInput.Sharp/Native/RawMouse.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
/// <summary>
/// RAWMOUSE
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public readonly struct RawMouse
{
readonly RawMouseFlags usFlags;
readonly ushort usReserved;
readonly RawMouseButtonFlags usButtonFlags;
readonly short usButtonData;
readonly uint ulRawButtons;
readonly int lLastX;
readonly int lLastY;
readonly uint ulExtraInformation;
public RawMouseFlags Flags => usFlags;
public RawMouseButtonFlags Buttons => usButtonFlags;
public int ButtonData => usButtonData;
public uint RawButtons => ulRawButtons;
public int LastX => lLastX;
public int LastY => lLastY;
public uint ExtraInformation => ulExtraInformation;
public override string ToString() =>
$"{{X: {LastX}, Y: {LastY}, Flags: {Flags}, Buttons: {Buttons}, Data: {ButtonData}}}";
}
/// <summary>
/// MOUSE_*
/// </summary>
[Flags]
public enum RawMouseFlags : ushort
{
/// <summary>
/// MOUSE_MOVE_RELATIVE
/// </summary>
None = 0,
/// <summary>
/// MOUSE_MOVE_ABSOLUTE
/// </summary>
MoveAbsolute = 1,
/// <summary>
/// MOUSE_VIRTUAL_DESKTOP
/// </summary>
VirtualDesktop = 2,
/// <summary>
/// MOUSE_ATTRIBUTES_CHANGED
/// </summary>
AttributesChanged = 4,
}
/// <summary>
/// RI_MOUSE_*
/// </summary>
[Flags]
public enum RawMouseButtonFlags : ushort
{
None,
/// <summary>
/// RI_MOUSE_LEFT_BUTTON_DOWN
/// </summary>
LeftButtonDown = 0x0001,
/// <summary>
/// RI_MOUSE_LEFT_BUTTON_UP
/// </summary>
LeftButtonUp = 0x0002,
/// <summary>
/// RI_MOUSE_RIGHT_BUTTON_DOWN
/// </summary>
RightButtonDown = 0x0004,
/// <summary>
/// RI_MOUSE_RIGHT_BUTTON_UP
/// </summary>
RightButtonUp = 0x0008,
/// <summary>
/// RI_MOUSE_MIDDLE_BUTTON_DOWN
/// </summary>
MiddleButtonDown = 0x0010,
/// <summary>
/// RI_MOUSE_MIDDLE_BUTTON_UP
/// </summary>
MiddleButtonUp = 0x0020,
/// <summary>
/// RI_MOUSE_BUTTON_4_DOWN
/// </summary>
Button4Down = 0x0040,
/// <summary>
/// RI_MOUSE_BUTTON_4_UP
/// </summary>
Button4Up = 0x0080,
/// <summary>
/// RI_MOUSE_BUTTON_5_DOWN
/// </summary>
Button5Down = 0x0100,
/// <summary>
/// RI_MOUSE_BUTTON_5_UP
/// </summary>
Button5Up = 0x0200,
/// <summary>
/// RI_MOUSE_WHEEL
/// </summary>
MouseWheel = 0x0400,
/// <summary>
/// RI_MOUSE_HWHEEL
/// </summary>
MouseHorizontalWheel = 0x0800,
}
================================================
FILE: RawInput.Sharp/Native/User32.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace Linearstar.Windows.RawInput.Native;
public static class User32
{
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputDeviceList([Out] RawInputDeviceListItem[]? pRawInputDeviceList, ref uint puiNumDevices, uint cbSize);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoBehavior uiBehavior, IntPtr pData, out uint pcbSize);
[DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
static extern uint GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoBehavior uiBehavior, StringBuilder pData, in uint pcbSize);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoBehavior uiBehavior, out RawInputDeviceInfo pData, in uint pcbSize);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputDeviceInfo(IntPtr hDevice, RawInputDeviceInfoBehavior uiBehavior, [Out] byte[] pData, in uint pcbSize);
[DllImport("user32", SetLastError = true)]
static extern bool RegisterRawInputDevices(RawInputDeviceRegistration[] pRawInputDevices, uint uiNumDevices, uint cbSize);
[DllImport("user32", SetLastError = true)]
static extern uint GetRegisteredRawInputDevices([Out] RawInputDeviceRegistration[]? pRawInputDevices, ref uint puiNumDevices, uint cbSize);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputData(IntPtr hRawInput, RawInputGetBehavior uiBehavior, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputData(IntPtr hRawInput, RawInputGetBehavior uiBehavior, out RawInputHeader pData, ref uint pcbSize, uint cbSizeHeader);
[DllImport("user32", SetLastError = true)]
static extern uint GetRawInputBuffer(IntPtr pData, ref uint pcbSize, uint cbSizeHeader);
[DllImport("user32", SetLastError = true)]
static extern IntPtr DefRawInputProc(byte[] paRawInput, int nInput, uint cbSizeHeader);
public enum RawInputGetBehavior : uint
{
Input = 0x10000003,
Header = 0x10000005,
}
public static RawInputDeviceListItem[] GetRawInputDeviceList()
{
var size = (uint)MarshalEx.SizeOf<RawInputDeviceListItem>();
// Get device count by passing null for pRawInputDeviceList.
uint deviceCount = 0;
GetRawInputDeviceList(null, ref deviceCount, size);
// Now, fill the buffer using the device count.
var devices = new RawInputDeviceListItem[deviceCount];
GetRawInputDeviceList(devices, ref deviceCount, size).EnsureSuccess();
return devices;
}
public static string? GetRawInputDeviceName(RawInputDeviceHandle device)
{
var deviceHandle = RawInputDeviceHandle.GetRawValue(device);
// Get the length of the device name first.
// For RIDI_DEVICENAME, the value in the pcbSize is the character count instead of the byte count.
GetRawInputDeviceInfo(deviceHandle, RawInputDeviceInfoBehavior.DeviceName, IntPtr.Zero, out var size);
if (size <= 2) return null;
var sb = new StringBuilder((int)size);
GetRawInputDeviceInfo(deviceHandle, RawInputDeviceInfoBehavior.DeviceName, sb, in size).EnsureSuccess();
return sb.ToString();
}
public static RawInputDeviceInfo GetRawInputDeviceInfo(RawInputDeviceHandle device)
{
var deviceHandle = RawInputDeviceHandle.GetRawValue(device);
var size = (uint)MarshalEx.SizeOf<RawInputDeviceInfo>();
GetRawInputDeviceInfo(deviceHandle, RawInputDeviceInfoBehavior.DeviceInfo, out var deviceInfo, in size).EnsureSuccess();
return deviceInfo;
}
public static byte[] GetRawInputDevicePreparsedData(RawInputDeviceHandle device)
{
var deviceHandle = RawInputDeviceHandle.GetRawValue(device);
GetRawInputDeviceInfo(deviceHandle, RawInputDeviceInfoBehavior.PreparsedData, IntPtr.Zero, out var size);
if (size == 0) return new byte[0];
var rt = new byte[size];
GetRawInputDeviceInfo(deviceHandle, RawInputDeviceInfoBehavior.PreparsedData, rt, in size).EnsureSuccess();
return rt;
}
public static void RegisterRawInputDevices(params RawInputDeviceRegistration[] devices)
{
RegisterRawInputDevices(devices, (uint)devices.Length, (uint)MarshalEx.SizeOf<RawInputDeviceRegistration>()).EnsureSuccess();
}
public static RawInputDeviceRegistration[] GetRegisteredRawInputDevices()
{
var size = (uint)MarshalEx.SizeOf<RawInputDeviceRegistration>();
uint count = 0;
GetRegisteredRawInputDevices(null, ref count, size);
var rt = new RawInputDeviceRegistration[count];
GetRegisteredRawInputDevices(rt, ref count, size).EnsureSuccess();
return rt;
}
public static RawInputHeader GetRawInputDataHeader(RawInputHandle rawInput)
{
var hRawInput = RawInputHandle.GetRawValue(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
var size = headerSize;
GetRawInputData(hRawInput, RawInputGetBehavior.Header, out var header, ref size, headerSize).EnsureSuccess();
return header;
}
public static uint GetRawInputDataSize(RawInputHandle rawInput)
{
var hRawInput = RawInputHandle.GetRawValue(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
uint size = 0;
GetRawInputData(hRawInput, RawInputGetBehavior.Input, IntPtr.Zero, ref size, headerSize);
return size;
}
public static void GetRawInputData(RawInputHandle rawInput, IntPtr ptr, uint size)
{
var hRawInput = RawInputHandle.GetRawValue(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
GetRawInputData(hRawInput, RawInputGetBehavior.Input, ptr, ref size, headerSize).EnsureSuccess();
}
public static unsafe RawMouse GetRawInputMouseData(RawInputHandle rawInput, out RawInputHeader header)
{
var size = GetRawInputDataSize(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
var bytes = new byte[size];
fixed (byte* bytesPtr = bytes)
{
GetRawInputData(rawInput, (IntPtr)bytesPtr, size);
header = *(RawInputHeader*)bytesPtr;
return *(RawMouse*)(bytesPtr + headerSize);
}
}
public static unsafe RawKeyboard GetRawInputKeyboardData(RawInputHandle rawInput, out RawInputHeader header)
{
var size = GetRawInputDataSize(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
var bytes = new byte[size];
fixed (byte* bytesPtr = bytes)
{
GetRawInputData(rawInput, (IntPtr)bytesPtr, size);
header = *(RawInputHeader*)bytesPtr;
return *(RawKeyboard*)(bytesPtr + headerSize);
}
}
public static unsafe RawHid GetRawInputHidData(RawInputHandle rawInput, out RawInputHeader header)
{
var size = GetRawInputDataSize(rawInput);
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
var bytes = new byte[size];
fixed (byte* bytesPtr = bytes)
{
GetRawInputData(rawInput, (IntPtr)bytesPtr, size);
header = *(RawInputHeader*)bytesPtr;
return RawHid.FromPointer(bytesPtr + headerSize);
}
}
public static uint GetRawInputBufferSize()
{
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
uint size = 0;
GetRawInputBuffer(IntPtr.Zero, ref size, headerSize);
return size;
}
public static uint GetRawInputBuffer(IntPtr ptr, uint size)
{
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
return GetRawInputBuffer(ptr, ref size, headerSize).EnsureSuccess();
}
public static void DefRawInputProc(byte[] paRawInput)
{
var headerSize = (uint)MarshalEx.SizeOf<RawInputHeader>();
DefRawInputProc(paRawInput, paRawInput.Length, headerSize);
}
public static bool EnsureSuccess(this bool result)
{
if (!result) throw new Win32ErrorException();
return result;
}
public static uint EnsureSuccess(this uint result)
{
if (result == unchecked((uint)-1)) throw new Win32ErrorException();
return result;
}
}
================================================
FILE: RawInput.Sharp/Native/Win32ErrorException.cs
================================================
using System;
using System.Runtime.InteropServices;
namespace Linearstar.Windows.RawInput.Native;
public class Win32ErrorException : Exception
{
public Win32ErrorException()
: this(Marshal.GetLastWin32Error())
{
}
public Win32ErrorException(int win32ErrorCode)
: base(Kernel32.FormatMessage(win32ErrorCode))
{
}
}
================================================
FILE: RawInput.Sharp/RawInput.Sharp.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<LangVersion>10</LangVersion>
<RootNamespace>Linearstar.Windows.RawInput</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Company>Linearstar</Company>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>A simple wrapper library for Raw Input.</Description>
<Copyright>Copyright (c) 2019 mfakane</Copyright>
<Authors>mfakane</Authors>
<PackageLicenseExpression>Zlib</PackageLicenseExpression>
<Version>0.1.3</Version>
<AssemblyVersion>0.0.0.0</AssemblyVersion>
<FileVersion>0.0.0.0</FileVersion>
<PackageTags>Windows RawInput</PackageTags>
<RepositoryUrl>https://github.com/mfakane/rawinput-sharp</RepositoryUrl>
<Nullable>enable</Nullable>
<TargetFrameworks>netstandard1.1;net461;net462;net47;net471;net472;net48;net7.0</TargetFrameworks>
</PropertyGroup>
</Project>
================================================
FILE: RawInput.Sharp/RawInputData.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public abstract class RawInputData
{
RawInputDevice? device;
public RawInputHeader Header { get; }
public RawInputDevice? Device =>
device ??= Header.DeviceHandle != RawInputDeviceHandle.Zero
? RawInputDevice.FromHandle(Header.DeviceHandle)
: null;
protected RawInputData(RawInputHeader header)
{
Header = header;
}
public static RawInputData FromHandle(IntPtr lParam)
=> FromHandle((RawInputHandle)lParam);
public static RawInputData FromHandle(RawInputHandle rawInput)
{
var header = User32.GetRawInputDataHeader(rawInput);
switch (header.Type)
{
case RawInputDeviceType.Mouse:
return new RawInputMouseData(header, User32.GetRawInputMouseData(rawInput, out _));
case RawInputDeviceType.Keyboard:
return new RawInputKeyboardData(header, User32.GetRawInputKeyboardData(rawInput, out _));
case RawInputDeviceType.Hid:
return RawInputHidData.Create(header, User32.GetRawInputHidData(rawInput, out _));
default:
throw new ArgumentException();
}
}
static unsafe RawInputData ParseRawInputBufferItem(byte* ptr)
{
var header = *(RawInputHeader*)ptr;
var headerSize = MarshalEx.SizeOf<RawInputHeader>();
var dataPtr = ptr + headerSize;
// RAWINPUT structure must be aligned by 8 bytes on WOW64
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputbuffer#remarks
if (EnvironmentEx.Is64BitProcess && EnvironmentEx.Is64BitOperatingSystem) dataPtr += 8;
switch (header.Type)
{
case RawInputDeviceType.Mouse:
return new RawInputMouseData(header, *(RawMouse*)dataPtr);
case RawInputDeviceType.Keyboard:
return new RawInputKeyboardData(header, *(RawKeyboard*)dataPtr);
case RawInputDeviceType.Hid:
return RawInputHidData.Create(header, RawHid.FromPointer(dataPtr));
default:
throw new ArgumentException();
}
}
public static unsafe RawInputData[] GetBufferedData(int bufferSize = 8)
{
var itemSize = User32.GetRawInputBufferSize();
if (itemSize == 0) return new RawInputData[0];
var bytes = new byte[itemSize * bufferSize];
fixed (byte* bytesPtr = bytes)
{
var count = User32.GetRawInputBuffer((IntPtr)bytesPtr, (uint)bytes.Length);
if (count == 0) return new RawInputData[0];
var result = new RawInputData[count];
for (int i = 0, offset = 0; i < result.Length; i++)
{
var data = ParseRawInputBufferItem(bytesPtr + offset);
result[i] = data;
offset = Align(offset + data.Header.Size);
}
return result;
}
}
protected static int Align(int x) => (x + IntPtr.Size - 1) & ~(IntPtr.Size - 1);
public static void DefRawInputProc(RawInputData[] data) =>
User32.DefRawInputProc(data.SelectMany(i => i.ToStructure()).ToArray());
public abstract byte[] ToStructure();
}
================================================
FILE: RawInput.Sharp/RawInputDevice.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public abstract class RawInputDevice
{
bool gotAttributes;
string? productName;
string? manufacturerName;
string? serialNumber;
protected RawInputDeviceInfo DeviceInfo { get; }
public RawInputDeviceHandle Handle { get; }
public RawInputDeviceType DeviceType => DeviceInfo.Type;
public string? DevicePath { get; }
public string? ManufacturerName
{
get
{
if (manufacturerName == null) GetAttributesOnce();
return manufacturerName;
}
}
public string? ProductName
{
get
{
if (productName == null) GetAttributesOnce();
return productName;
}
}
public string? SerialNumber
{
get
{
if (serialNumber == null) GetAttributesOnce();
return serialNumber;
}
}
public bool IsConnected =>
DevicePath != null && CfgMgr32.TryLocateDevNode(DevicePath, CfgMgr32.LocateDevNodeFlags.Normal, out _) == ConfigReturnValue.Success;
public abstract HidUsageAndPage UsageAndPage { get; }
public abstract int VendorId { get; }
public abstract int ProductId { get; }
void GetAttributesOnce()
{
if (gotAttributes) return;
gotAttributes = true;
if (DevicePath == null) return;
GetAttributesFromHidD();
if (manufacturerName == null || productName == null) GetAttributesFromCfgMgr();
}
void GetAttributesFromHidD()
{
if (DevicePath == null || !HidD.TryOpenDevice(DevicePath, out var device)) return;
try
{
manufacturerName ??= HidD.GetManufacturerString(device);
productName ??= HidD.GetProductString(device);
serialNumber ??= HidD.GetSerialNumberString(device);
}
finally
{
HidD.CloseDevice(device);
}
}
void GetAttributesFromCfgMgr()
{
if (DevicePath == null) return;
var path = DevicePath.Substring(4).Replace('#', '\\');
if (path.Contains("{")) path = path.Substring(0, path.IndexOf('{') - 1);
var device = CfgMgr32.LocateDevNode(path, CfgMgr32.LocateDevNodeFlags.Phantom);
manufacturerName ??= CfgMgr32.GetDevNodePropertyString(device, in DevicePropertyKey.DeviceManufacturer);
productName ??= CfgMgr32.GetDevNodePropertyString(device, in DevicePropertyKey.DeviceFriendlyName);
productName ??= CfgMgr32.GetDevNodePropertyString(device, in DevicePropertyKey.Name);
}
protected RawInputDevice(RawInputDeviceHandle device, RawInputDeviceInfo deviceInfo)
{
Handle = device;
DevicePath = User32.GetRawInputDeviceName(device);
DeviceInfo = deviceInfo;
}
public static RawInputDevice FromHandle(RawInputDeviceHandle device)
{
var deviceInfo = User32.GetRawInputDeviceInfo(device);
switch (deviceInfo.Type)
{
case RawInputDeviceType.Mouse:
return new RawInputMouse(device, deviceInfo);
case RawInputDeviceType.Keyboard:
return new RawInputKeyboard(device, deviceInfo);
case RawInputDeviceType.Hid:
return RawInputDigitizer.IsSupported(deviceInfo.Hid.UsageAndPage)
? new RawInputDigitizer(device, deviceInfo)
: new RawInputHid(device, deviceInfo);
default:
throw new ArgumentException();
}
}
/// <summary>
/// Gets available devices that can be handled with Raw Input.
/// </summary>
/// <returns>Array of <see cref="RawInputDevice"/>, which contains mouse as a <see cref="RawInputMouse"/>, keyboard as a <see cref="RawInputKeyboard"/>, and any other HIDs as a <see cref="RawInputHid"/>.</returns>
public static RawInputDevice[] GetDevices()
{
var devices = User32.GetRawInputDeviceList();
return devices.Select(i => FromHandle(i.Device)).ToArray();
}
public byte[] GetPreparsedData() =>
User32.GetRawInputDevicePreparsedData(Handle);
public static void RegisterDevice(HidUsageAndPage usageAndPage, RawInputDeviceFlags flags, IntPtr hWndTarget) =>
RegisterDevice(new RawInputDeviceRegistration(usageAndPage, flags, hWndTarget));
public static void RegisterDevice(params RawInputDeviceRegistration[] devices) =>
User32.RegisterRawInputDevices(devices);
public static void UnregisterDevice(HidUsageAndPage usageAndPage) =>
RegisterDevice(usageAndPage, RawInputDeviceFlags.Remove, IntPtr.Zero);
public static RawInputDeviceRegistration[] GetRegisteredDevices() =>
User32.GetRegisteredRawInputDevices();
}
================================================
FILE: RawInput.Sharp/RawInputDeviceFlags.cs
================================================
using System;
namespace Linearstar.Windows.RawInput;
/// <summary>
/// RIDEV_*
/// </summary>
[Flags]
public enum RawInputDeviceFlags
{
None,
/// <summary>
/// RIDEV_REMOVE. Removes the top level collection from the inclusion list.
/// </summary>
Remove = 0x1,
/// <summary>
/// RIDEV_EXCLUDE. Specifies the top level collections to exclude when reading a complete usage page.
/// </summary>
Exclude = 0x10,
/// <summary>
/// RIDEV_PAGEONLY. Specifies all devices whose top level collection is from the specified <see cref="RawInputDeviceRegistration.UsagePage"/>.
/// </summary>
PageOnly = 0x20,
/// <summary>
/// RIDEV_NOLEGACY. Prevents any devices specified by <see cref="RawInputDeviceRegistration.UsagePage"/> or <see cref="RawInputDeviceRegistration.Usage"/> from generating legacy messages.
/// </summary>
NoLegacy = 0x30,
/// <summary>
/// RIDEV_INPUTSINK. Enables the caller to receive the input even when the caller is not in the foreground. Note that <see cref="RawInputDeviceRegistration.HwndTarget"/> must be specified.
/// </summary>
InputSink = 0x100,
/// <summary>
/// RIDEV_CAPTUREMOUSE. The mouse button click does not activate the other window.
/// </summary>
CaptureMouse = 0x200,
/// <summary>
/// RIDEV_NOHOTKEYS. The application-defined keyboard device hotkeys are not handled. This can be specified even if <see cref="NoLegacy"/> is not specified and <see cref="RawInputDeviceRegistration.HwndTarget"/> is <see cref="IntPtr.Zero"/>.
/// </summary>
NoHotKeys = 0x200,
/// <summary>
/// RIDEV_APPKEYS. The application command keys are handled. This can be specified only if <see cref="NoLegacy"/> is specified for a keyboard device.
/// </summary>
AppKeys = 0x400,
/// <summary>
/// RIDEV_EXINPUTSINK. Enables the caller to receive input in the background only if the foreground application does not process it.
/// </summary>
ExInputSink = 0x1000,
/// <summary>
/// RIDEV_DEVNOTIFY. Enables the caller to receive WM_INPUT_DEVICE_CHANGE notifications for device arrival and device removal.
/// </summary>
DevNotify = 0x2000,
}
================================================
FILE: RawInput.Sharp/RawInputDeviceRegistration.cs
================================================
using System;
namespace Linearstar.Windows.RawInput;
public readonly struct RawInputDeviceRegistration
{
readonly ushort usUsagePage;
readonly ushort usUsage;
readonly RawInputDeviceFlags dwFlags;
readonly IntPtr hwndTarget;
public ushort UsagePage => usUsagePage;
public ushort Usage => usUsage;
public RawInputDeviceFlags Flags => dwFlags;
public IntPtr HwndTarget => hwndTarget;
public RawInputDeviceRegistration(HidUsageAndPage usageAndPage, RawInputDeviceFlags flags, IntPtr hWndTarget)
: this(usageAndPage.UsagePage, usageAndPage.Usage, flags, hWndTarget)
{
}
public RawInputDeviceRegistration(ushort usagePage, ushort usage, RawInputDeviceFlags flags, IntPtr hWndTarget)
{
usUsagePage = usagePage;
usUsage = usage;
dwFlags = flags;
hwndTarget = hWndTarget;
}
}
================================================
FILE: RawInput.Sharp/RawInputDeviceType.cs
================================================
namespace Linearstar.Windows.RawInput;
public enum RawInputDeviceType
{
Mouse,
Keyboard,
Hid,
}
================================================
FILE: RawInput.Sharp/RawInputDigitizer.cs
================================================
using System;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputDigitizer : RawInputHid
{
public static readonly HidUsageAndPage UsageContactCount = new(0x0D, 0x54);
public int MaxContactCount => Reader.ValueSets.SelectMany(x => x).FirstOrDefault(x => x.LinkUsageAndPage == UsageAndPage && x.UsageAndPage == UsageContactCount)?.MaxValue ?? 1;
internal RawInputDigitizer(RawInputDeviceHandle device, RawInputDeviceInfo deviceInfo)
: base(device, deviceInfo)
{
if (!IsSupported(deviceInfo.Hid.UsageAndPage)) throw new ArgumentException($"UsagePage and Usage {deviceInfo.Hid.UsageAndPage} is not supported as a digitizer.", nameof(deviceInfo));
}
public static bool IsSupported(HidUsageAndPage usageAndPage) =>
usageAndPage.UsagePage == 0x0D;
}
================================================
FILE: RawInput.Sharp/RawInputDigitizerButton.cs
================================================
using System.Collections.Generic;
using System.Linq;
namespace Linearstar.Windows.RawInput;
class RawInputDigitizerButton
{
public static readonly HidUsageAndPage UsageInRange = new(0x0D, 0x32);
public static readonly HidUsageAndPage UsageInvert = new(0x0D, 0x3c);
public static readonly HidUsageAndPage UsageTipSwitch = new(0x0D, 0x42);
public static readonly HidUsageAndPage UsageBarrel = new(0x0D, 0x44);
public static readonly HidUsageAndPage UsageEraser = new(0x0D, 0x45);
public static readonly HidUsageAndPage UsageConfidence = new(0x0D, 0x47);
public bool? InRange { get; }
public bool? IsInverted { get; }
public bool IsDown { get; }
public bool? IsBarrel { get; }
public bool? IsEraser { get; }
public bool? HasConfidence { get; }
RawInputDigitizerButton(bool? inRange, bool? isInverted, bool isDown, bool? isBarrel, bool? isEraser, bool? hasConfidence)
{
InRange = inRange;
IsInverted = isInverted;
IsDown = isDown;
IsBarrel = isBarrel;
IsEraser = isEraser;
HasConfidence = hasConfidence;
}
internal static IEnumerable<RawInputDigitizerButton> Read(
ILookup<HidUsageAndPage, HidButtonState> buttonStatesByLinkCollection)
{
var buttonStates = buttonStatesByLinkCollection.ToDictionary(x => x.Key, x => x.ToList());
while (buttonStates[UsageTipSwitch].Any())
{
var inRange = PopState(UsageInRange);
var isInverted = PopState(UsageInvert);
var isDown = PopState(UsageTipSwitch) ?? false;
var isBarrel = PopState(UsageBarrel);
var isEraser = PopState(UsageEraser);
var hasConfidence = PopState(UsageConfidence);
yield return new RawInputDigitizerButton(inRange, isInverted, isDown, isBarrel, isEraser, hasConfidence);
}
bool? PopState(HidUsageAndPage usageAndPage)
{
if (buttonStates?.TryGetValue(usageAndPage, out var usageStates) != true) return null;
if (usageStates?.Any() != true) return null;
var isActive = usageStates[0].IsActive;
usageStates.RemoveAt(0);
return isActive;
}
}
}
================================================
FILE: RawInput.Sharp/RawInputDigitizerContact.cs
================================================
using System.Collections.Generic;
using System.Linq;
namespace Linearstar.Windows.RawInput;
public class RawInputDigitizerContact
{
public static readonly HidUsageAndPage UsageX = new(0x01, 0x30);
public static readonly HidUsageAndPage UsageY = new(0x01, 0x31);
public static readonly HidUsageAndPage UsagePressure = new(0x0D, 0x30);
public static readonly HidUsageAndPage UsageWidth = new(0x0D, 0x48);
public static readonly HidUsageAndPage UsageHeight = new(0x0D, 0x49);
public static readonly HidUsageAndPage UsageIdentifier = new(0x0D, 0x51);
readonly RawInputDigitizerButton button;
public RawInputDigitizerContactKind Kind
{
get
{
if (button.IsEraser == true) return RawInputDigitizerContactKind.Eraser;
if (button.IsDown)
return button.HasConfidence == true
? RawInputDigitizerContactKind.Finger
: RawInputDigitizerContactKind.Pen;
return button.InRange == true
? RawInputDigitizerContactKind.Hover
: RawInputDigitizerContactKind.None;
}
}
public int X { get; }
public int Y { get; }
public int MinX { get; }
public int MinY { get; }
public int MaxX { get; }
public int MaxY { get; }
public int? Pressure { get; }
public int? MaxPressure { get; }
public bool? IsInverted => button.IsInverted;
public bool? IsButtonDown => button.IsDown;
public int? Width { get; }
public int? Height { get; }
public int? Identifier { get; }
RawInputDigitizerContact(
RawInputDigitizerButton button,
HidValueState x,
HidValueState y,
HidValueState? pressure,
HidValueState? width,
HidValueState? height,
HidValueState? identifier)
{
this.button = button;
X = x.CurrentValue;
Y = y.CurrentValue;
MinX = x.Value.MinValue;
MinY = y.Value.MinValue;
MaxX = x.Value.MaxValue;
MaxY = y.Value.MaxValue;
Pressure = pressure?.CurrentValue;
MaxPressure = pressure?.Value.MaxValue;
Width = width?.CurrentValue;
Height = height?.CurrentValue;
Identifier = identifier?.CurrentValue;
}
internal static IEnumerable<RawInputDigitizerContact> Read(
RawInputDigitizerButton button,
IEnumerable<HidValueState> valueStatesPerLinkCollection)
{
var valueStates = valueStatesPerLinkCollection
.ToLookup(x => x.Value.UsageAndPage)
.ToDictionary(x => x.Key, x => x.ToList());
while (valueStates[UsageX].Any())
{
var x = PopState(UsageX);
var y = PopState(UsageY);
if (x == null || y == null) break;
var pressure = PopState(UsagePressure);
var width = PopState(UsageWidth);
var height = PopState(UsageHeight);
var identifier = PopState(UsageIdentifier);
yield return new RawInputDigitizerContact(
button,
x,
y,
pressure,
width,
height,
identifier
);
}
HidValueState? PopState(HidUsageAndPage usageAndPage)
{
if (valueStates?.TryGetValue(usageAndPage, out var usageStates) != true) return null;
if (usageStates?.Any() != true) return null;
var state = usageStates[0];
usageStates.RemoveAt(0);
return state;
}
}
public override string ToString() =>
"{" + string.Join(", ", new[]
{
$"X: {X}/{MaxX}",
$"Y: {Y}/{MaxY}",
$"Kind: {Kind}",
Pressure.HasValue ? $"Pressure: {Pressure}/{MaxPressure}" : null,
IsInverted.HasValue ? $"Inverted: {IsInverted}" : null,
IsButtonDown.HasValue ? $"Button: {IsButtonDown}" : null,
Width.HasValue ? $"Width: {Width}" : null,
Height.HasValue ? $"Height: {Height}" : null,
Identifier.HasValue ? $"Identifier: {Identifier}" : null,
}.Where(i => i != null)) + "}";
}
================================================
FILE: RawInput.Sharp/RawInputDigitizerContactKind.cs
================================================
namespace Linearstar.Windows.RawInput;
public enum RawInputDigitizerContactKind
{
None,
Finger,
Hover,
Pen,
Eraser,
}
================================================
FILE: RawInput.Sharp/RawInputDigitizerData.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputDigitizerData : RawInputHidData
{
public int ContactsCount { get; }
public int MaxContactsCount { get; }
public RawInputDigitizerContact[] Contacts { get; }
public RawInputDigitizerData(RawInputHeader header, RawHid hid)
: base(header, hid)
{
if (Device is not RawInputDigitizer digitizer) throw new ArgumentException($"Device specified in the {nameof(header)} was not a valid digitizer.", nameof(header));
var contactButtonStates = ButtonSetStates
.SelectMany(x => x)
.Where(x => x.Button.LinkUsageAndPage != digitizer.UsageAndPage)
.ToLookup(x => x.Button.LinkCollection);
var contactValueStates = ValueSetStates
.SelectMany(x => x)
.Where(x => x.Value.LinkUsageAndPage != digitizer.UsageAndPage)
.ToLookup(x => x.Value.LinkCollection);
var contactsCountUsages = ValueSetStates
.SelectMany(x => x)
.Where(x => x.Value.LinkUsageAndPage == digitizer.UsageAndPage && x.Value.UsageAndPage == RawInputDigitizer.UsageContactCount)
.ToArray();
var contactsCount = contactsCountUsages.Select(x => x.CurrentValue).DefaultIfEmpty(1).Max();
Contacts = EnumerateContacts().ToArray();
this.ContactsCount = contactsCountUsages.Any() ? contactsCount : Math.Min(Contacts.Length, 1);
this.MaxContactsCount = contactsCountUsages.Select(x => x.Value.MaxValue).DefaultIfEmpty(1).Max();
IEnumerable<RawInputDigitizerContact> EnumerateContacts()
{
foreach (var buttonStates in contactButtonStates)
foreach (var button in RawInputDigitizerButton.Read(buttonStates.ToLookup(x => x.Button.UsageAndPage)))
foreach (var contact in RawInputDigitizerContact.Read(button, contactValueStates[buttonStates.Key]))
if (buttonStates.Key <= contactsCount)
yield return contact;
}
}
}
================================================
FILE: RawInput.Sharp/RawInputHid.cs
================================================
using System;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputHid : RawInputDevice
{
readonly Lazy<HidReader> hidReader;
public override HidUsageAndPage UsageAndPage => DeviceInfo.Hid.UsageAndPage;
public override int VendorId => DeviceInfo.Hid.VendorId;
public override int ProductId => DeviceInfo.Hid.ProductId;
public int Version => DeviceInfo.Hid.VersionNumber;
public HidReader Reader => hidReader.Value;
internal RawInputHid(RawInputDeviceHandle device, RawInputDeviceInfo deviceInfo)
: base(device, deviceInfo)
{
if (deviceInfo.Type != RawInputDeviceType.Hid) throw new ArgumentException($"Device type must be {RawInputDeviceType.Hid}.", nameof(deviceInfo));
hidReader = new Lazy<HidReader>(() => new HidReader(new HidPreparsedByteArrayData(GetPreparsedData())));
}
}
================================================
FILE: RawInput.Sharp/RawInputHidData.cs
================================================
using System.Linq;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputHidData : RawInputData
{
public new RawInputHid? Device => (RawInputHid?)base.Device;
public RawHid Hid { get; }
public HidButtonSetState[] ButtonSetStates =>
Device != null
? Hid.ToHidReports().SelectMany(report => Device.Reader.ButtonSets.Select(x => x.GetStates(report))).ToArray()
: new HidButtonSetState[0];
public HidValueSetState[] ValueSetStates =>
Device != null
? Hid.ToHidReports().SelectMany(report => Device.Reader.ValueSets.Select(x => x.GetStates(report))).ToArray()
: new HidValueSetState[0];
protected RawInputHidData(RawInputHeader header, RawHid hid)
: base(header) =>
Hid = hid;
public static RawInputHidData Create(RawInputHeader header, RawHid hid)
{
var device = header.DeviceHandle != RawInputDeviceHandle.Zero ? RawInputDevice.FromHandle(header.DeviceHandle) : null;
if (device != null && RawInputDigitizer.IsSupported(device.UsageAndPage))
return new RawInputDigitizerData(header, hid);
return new RawInputHidData(header, hid);
}
public override unsafe byte[] ToStructure()
{
var headerSize = MarshalEx.SizeOf<RawInputHeader>();
var hid = Hid.ToStructure();
var bytes = new byte[Align(headerSize + hid.Length)];
fixed (byte* bytesPtr = bytes)
*(RawInputHeader*) bytesPtr = Header;
hid.CopyTo(bytes, headerSize);
return bytes;
}
public override string ToString() =>
$"{{{Header}, {Hid}}}";
}
================================================
FILE: RawInput.Sharp/RawInputKeyboard.cs
================================================
using System;
using System.Globalization;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputKeyboard : RawInputDevice
{
public override HidUsageAndPage UsageAndPage => HidUsageAndPage.Keyboard;
public override int VendorId =>
DevicePath?.Contains("VID_") == true
? int.Parse(DevicePath.Substring(DevicePath.IndexOf("VID_", StringComparison.Ordinal) + 4, 4), NumberStyles.HexNumber)
: 0;
public override int ProductId =>
DevicePath?.Contains("PID_") == true
? int.Parse(DevicePath.Substring(DevicePath.IndexOf("PID_", StringComparison.Ordinal) + 4, 4), NumberStyles.HexNumber)
: 0;
public int KeyboardType => DeviceInfo.Keyboard.KeyboardType;
public int KeyboardSubType => DeviceInfo.Keyboard.KeyboardSubType;
public int KeyboardMode => DeviceInfo.Keyboard.KeyboardMode;
public int FunctionKeyCount => DeviceInfo.Keyboard.FunctionKeyCount;
public int IndicatorCount => DeviceInfo.Keyboard.IndicatorCount;
public int TotalKeyCount => DeviceInfo.Keyboard.TotalKeyCount;
internal RawInputKeyboard(RawInputDeviceHandle device, RawInputDeviceInfo deviceInfo)
: base(device, deviceInfo)
{
if (deviceInfo.Type != RawInputDeviceType.Keyboard) throw new ArgumentException($"Device type must be {RawInputDeviceType.Keyboard}", nameof(deviceInfo));
}
}
================================================
FILE: RawInput.Sharp/RawInputKeyboardData.cs
================================================
using System.Runtime.InteropServices;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputKeyboardData : RawInputData
{
public RawKeyboard Keyboard { get; }
public RawInputKeyboardData(RawInputHeader header, RawKeyboard keyboard)
: base(header) =>
Keyboard = keyboard;
public override unsafe byte[] ToStructure()
{
var headerSize = MarshalEx.SizeOf<RawInputHeader>();
var mouseSize = MarshalEx.SizeOf<RawKeyboard>();
var bytes = new byte[headerSize + mouseSize];
fixed (byte* bytesPtr = bytes)
{
*(RawInputHeader*)bytesPtr = Header;
*(RawKeyboard*)(bytesPtr + headerSize) = Keyboard;
}
return bytes;
}
public override string ToString() =>
$"{{{Header}, {Keyboard}}}";
}
================================================
FILE: RawInput.Sharp/RawInputMouse.cs
================================================
using System;
using System.Globalization;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputMouse : RawInputDevice
{
public override HidUsageAndPage UsageAndPage => HidUsageAndPage.Mouse;
public override int VendorId =>
DevicePath?.Contains("VID_") == true
? int.Parse(DevicePath.Substring(DevicePath.IndexOf("VID_", StringComparison.Ordinal) + 4, 4), NumberStyles.HexNumber)
: 0;
public override int ProductId =>
DevicePath?.Contains("PID_") == true
? int.Parse(DevicePath.Substring(DevicePath.IndexOf("PID_", StringComparison.Ordinal) + 4, 4), NumberStyles.HexNumber)
: 0;
public int Id => DeviceInfo.Mouse.Id;
public int ButtonCount => DeviceInfo.Mouse.ButtonCount;
public int SampleRate => DeviceInfo.Mouse.SampleRate;
public bool HasHorizontalWheel => DeviceInfo.Mouse.HasHorizontalWheel;
internal RawInputMouse(RawInputDeviceHandle device, RawInputDeviceInfo deviceInfo)
: base(device, deviceInfo)
{
if (deviceInfo.Type != RawInputDeviceType.Mouse) throw new ArgumentException($"Device type must be {RawInputDeviceType.Mouse}.", nameof(deviceInfo));
}
}
================================================
FILE: RawInput.Sharp/RawInputMouseData.cs
================================================
using System.Runtime.InteropServices;
using Linearstar.Windows.RawInput.Native;
namespace Linearstar.Windows.RawInput;
public class RawInputMouseData : RawInputData
{
public RawMouse Mouse { get; }
public RawInputMouseData(RawInputHeader header, RawMouse mouse)
: base(header) =>
Mouse = mouse;
public override unsafe byte[] ToStructure()
{
var headerSize = MarshalEx.SizeOf<RawInputHeader>();
var mouseSize = MarshalEx.SizeOf<RawMouse>();
var bytes = new byte[headerSize + mouseSize];
fixed (byte* bytesPtr = bytes)
{
*(RawInputHeader*)bytesPtr = Header;
*(RawMouse*)(bytesPtr + headerSize) = Mouse;
}
return bytes;
}
public override string ToString() =>
$"{{{Header}, {Mouse}}}";
}
================================================
FILE: RawInput.Sharp.DigitizerExample/MainForm.Designer.cs
================================================
namespace RawInput.Sharp.DigitizerExample;
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// textLabel
//
this.textLabel.AutoSize = true;
this.textLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.textLabel.Location = new System.Drawing.Point(0, 0);
this.textLabel.Name = "textLabel";
this.textLabel.Size = new System.Drawing.Size(38, 15);
this.textLabel.TabIndex = 0;
this.textLabel.Text = "Touch anywhere in this window.";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.textLabel);
this.Name = "MainForm";
this.Text = "Digitizer Example";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Label textLabel;
}
================================================
FILE: RawInput.Sharp.DigitizerExample/MainForm.cs
================================================
using Linearstar.Windows.RawInput;
namespace RawInput.Sharp.DigitizerExample;
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
RawInputDevice.RegisterDevice(HidUsageAndPage.Pen, RawInputDeviceFlags.None, this.Handle);
RawInputDevice.RegisterDevice(HidUsageAndPage.TouchScreen, RawInputDeviceFlags.None, this.Handle);
RawInputDevice.RegisterDevice(HidUsageAndPage.TouchPad, RawInputDeviceFlags.None, this.Handle);
}
protected override void WndProc(ref Message m)
{
const int WM_INPUT = 0x00FF;
if (m.Msg == WM_INPUT)
{
var data = RawInputData.FromHandle(m.LParam);
if (data is RawInputDigitizerData digitizerData)
{
var contacts = digitizerData.Contacts;
this.textLabel.Text =
$"Touch anywhere in this window.\r\n\r\nContacts: {digitizerData.ContactsCount}\r\n"
+ string.Join("\r\n", contacts.Select(x => x.ToString()));
}
}
base.WndProc(ref m);
}
}
================================================
FILE: RawInput.Sharp.DigitizerExample/MainForm.resx
================================================
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
================================================
FILE: RawInput.Sharp.DigitizerExample/Program.cs
================================================
namespace RawInput.Sharp.DigitizerExample;
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
================================================
FILE: RawInput.Sharp.DigitizerExample/RawInput.Sharp.DigitizerExample.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RawInput.Sharp\RawInput.Sharp.csproj" />
</ItemGroup>
</Project>
================================================
FILE: RawInput.Sharp.SimpleExample/Program.cs
================================================
using System;
using System.Linq;
using System.Windows.Forms;
using Linearstar.Windows.RawInput;
using RawInput.Sharp.SimpleExample;
// Get the devices that can be handled with Raw Input.
var devices = RawInputDevice.GetDevices();
// Keyboards will be returned as a RawInputKeyboard.
var keyboards = devices.OfType<RawInputKeyboard>();
// List them up.
foreach (var device in keyboards)
Console.WriteLine(
$"{device.DeviceType} {device.VendorId:X4}:{device.ProductId:X4} {device.ProductName}, {device.ManufacturerName}");
// To begin catching inputs, first make a window that listens WM_INPUT.
var window = new RawInputReceiverWindow();
window.Input += (sender, e) =>
{
// Catch your input here!
var data = e.Data;
Console.WriteLine(data);
};
try
{
// Register the HidUsageAndPage to watch any device.
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard,
RawInputDeviceFlags.ExInputSink | RawInputDeviceFlags.NoLegacy, window.Handle);
RawInputDevice.RegisterDevice(HidUsageAndPage.Mouse,
RawInputDeviceFlags.ExInputSink | RawInputDeviceFlags.NoLegacy, window.Handle);
Application.Run();
}
finally
{
RawInputDevice.UnregisterDevice(HidUsageAndPage.Keyboard);
}
================================================
FILE: RawInput.Sharp.SimpleExample/RawInput.Sharp.SimpleExample.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<OutputType>Exe</OutputType>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RawInput.Sharp\RawInput.Sharp.csproj" />
</ItemGroup>
</Project>
================================================
FILE: RawInput.Sharp.SimpleExample/RawInputEventArgs.cs
================================================
using System;
using Linearstar.Windows.RawInput;
namespace RawInput.Sharp.SimpleExample;
class RawInputEventArgs : EventArgs
{
public RawInputEventArgs(RawInputData data)
{
Data = data;
}
public RawInputData Data { get; }
}
================================================
FILE: RawInput.Sharp.SimpleExample/RawInputReceiverWindow.cs
================================================
using System;
using System.Windows.Forms;
using Linearstar.Windows.RawInput;
namespace RawInput.Sharp.SimpleExample;
sealed class RawInputReceiverWindow : NativeWindow
{
public event EventHandler<RawInputEventArgs>? Input;
public RawInputReceiverWindow()
{
CreateHandle(new CreateParams
{
X = 0,
Y = 0,
Width = 0,
Height = 0,
Style = 0x800000,
});
}
protected override void WndProc(ref Message m)
{
const int WM_INPUT = 0x00FF;
if (m.Msg == WM_INPUT)
{
var data = RawInputData.FromHandle(m.LParam);
Input?.Invoke(this, new RawInputEventArgs(data));
}
base.WndProc(ref m);
}
}
================================================
FILE: RawInput.Sharp.SimpleExample/app.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/App.xaml
================================================
<Application x:Class="RawInput.Sharp.SimpleExample.WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:RawInput.Sharp.SimpleExample.WPF"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/App.xaml.cs
================================================
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace RawInput.Sharp.SimpleExample.WPF
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/AssemblyInfo.cs
================================================
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/MainWindow.xaml
================================================
<Window x:Class="RawInput.Sharp.SimpleExample.WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:RawInput.Sharp.SimpleExample.WPF"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
</Grid>
</Window>
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/MainWindow.xaml.cs
================================================
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;
using Linearstar.Windows.RawInput;
namespace RawInput.Sharp.SimpleExample.WPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SourceInitialized += MainWindow_SourceInitialized;
}
private void MainWindow_SourceInitialized(object? sender, EventArgs e)
{
var windowInteropHelper = new WindowInteropHelper(this);
var hwnd = windowInteropHelper.Handle;
// Get the devices that can be handled with Raw Input.
var devices = RawInputDevice.GetDevices();
// register the keyboard device and you can register device which you need like mouse
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard,
RawInputDeviceFlags.ExInputSink | RawInputDeviceFlags.NoLegacy, hwnd);
HwndSource source = HwndSource.FromHwnd(hwnd);
source.AddHook(Hook);
}
private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
const int WM_INPUT = 0x00FF;
// You can read inputs by processing the WM_INPUT message.
if (msg == WM_INPUT)
{
// Create an RawInputData from the handle stored in lParam.
var data = RawInputData.FromHandle(lparam);
// You can identify the source device using Header.DeviceHandle or just Device.
var sourceDeviceHandle = data.Header.DeviceHandle;
var sourceDevice = data.Device;
// The data will be an instance of either RawInputMouseData, RawInputKeyboardData, or RawInputHidData.
// They contain the raw input data in their properties.
switch (data)
{
case RawInputMouseData mouse:
Debug.WriteLine(mouse.Mouse);
break;
case RawInputKeyboardData keyboard:
Debug.WriteLine(keyboard.Keyboard);
break;
case RawInputHidData hid:
Debug.WriteLine(hid.Hid);
break;
}
}
return IntPtr.Zero;
}
}
}
================================================
FILE: RawInput.Sharp.SimpleExample.WPF/RawInput.Sharp.SimpleExample.WPF.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RawInput.Sharp\RawInput.Sharp.csproj" />
</ItemGroup>
</Project>
================================================
FILE: RawInput.Sharp.SimpleExample.Win32/Program.cs
================================================
using Linearstar.Windows.RawInput;
using System.ComponentModel;
using System.Runtime.InteropServices;
var WindowClass = "HelperWindowClass";
var wind_class = new WNDCLASS
{
lpszClassName = Marshal.StringToHGlobalUni(WindowClass),
lpfnWndProc = (hWnd, msg, wParam, lParam) =>
{
const int WM_INPUT = 0x00FF;
// You can read inputs by processing the WM_INPUT message.
if (msg == WM_INPUT)
{
// Create an RawInputData from the handle stored in lParam.
var data = RawInputData.FromHandle(lParam);
// You can identify the source device using Header.DeviceHandle or just Device.
var sourceDeviceHandle = data.Header.DeviceHandle;
var sourceDevice = data.Device;
// The data will be an instance of either RawInputMouseData, RawInputKeyboardData, or RawInputHidData.
// They contain the raw input data in their properties.
switch (data)
{
case RawInputMouseData mouse:
Console.WriteLine(mouse.Mouse);
break;
case RawInputKeyboardData keyboard:
Console.WriteLine(keyboard.Keyboard);
break;
case RawInputHidData hid:
Console.WriteLine(hid.Hid);
break;
}
}
// The normal way to quit is sending WM_CLOSE message to the window
// if (msg == 0x0002) { // WM_DESTORY
// PostQuitMessage(0);
// return nint.Zero;
// }
// handle the messages here
return DefWindowProc(hWnd, msg, wParam, lParam);
}
};
ushort classAtom = RegisterClassW(ref wind_class);
if (classAtom == 0)
throw new Win32Exception();
const uint WS_EX_NOACTIVATE = 0x08000000;
const uint WS_POPUP = 0x80000000;
IntPtr hWnd = CreateWindowExW(
WS_EX_NOACTIVATE,
WindowClass,
"",
WS_POPUP,
0, 0, 0, 0,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero
);
if (hWnd == IntPtr.Zero)
throw new Win32Exception();
// Get the devices that can be handled with Raw Input.
var devices = RawInputDevice.GetDevices();
// register the keyboard device and you can register device which you need like mouse
RawInputDevice.RegisterDevice(HidUsageAndPage.Keyboard,
RawInputDeviceFlags.ExInputSink | RawInputDeviceFlags.NoLegacy, hWnd);
// Message loop
while (GetMessage(out var msg, IntPtr.Zero, 0, 0))
{
TranslateMessage(msg);
DispatchMessage(msg);
}
[DllImport("user32.dll")]
static extern bool GetMessage(out IntPtr lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
[DllImport("user32.dll")]
static extern bool TranslateMessage(in IntPtr lpMsg);
[DllImport("user32.dll")]
static extern IntPtr DispatchMessage(in IntPtr lpMsg);
[DllImport("user32.dll", SetLastError = true)]
static extern ushort RegisterClassW([In] ref WNDCLASS lpWndClass);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr CreateWindowExW(uint dwExStyle,
[MarshalAs(UnmanagedType.LPWStr)] string lpClassName,
[MarshalAs(UnmanagedType.LPWStr)] string lpWindowName,
uint dwStyle, int x, int y, int nWidth, int nHeight,
IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
[DllImport("user32.dll")]
static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
struct WNDCLASS
{
public uint style;
public WndProc lpfnWndProc;
public int cbClsExtra;
public int cbWndExtra;
public IntPtr hInstance;
public IntPtr hIcon;
public IntPtr hCursor;
public IntPtr hbrBackground;
public string lpszMenuName;
public nint lpszClassName;
}
================================================
FILE: RawInput.Sharp.SimpleExample.Win32/RawInput.Sharp.SimpleExample.Win32.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>true</PublishAot>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\RawInput.Sharp\RawInput.Sharp.csproj" />
</ItemGroup>
</Project>
================================================
FILE: RawInput.Sharp.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.33920.267
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RawInput.Sharp", "RawInput.Sharp\RawInput.Sharp.csproj", "{47C40BEA-5191-46A3-BE27-4B7A1B725C31}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8B433D11-9752-4F95-A83A-6C04CB02CE07}"
ProjectSection(SolutionItems) = preProject
LICENSE.txt = LICENSE.txt
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RawInput.Sharp.SimpleExample", "RawInput.Sharp.SimpleExample\RawInput.Sharp.SimpleExample.csproj", "{F129A5A1-95EA-41CF-98E3-ECB61BEB5040}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RawInput.Sharp.SimpleExample.WPF", "RawInput.Sharp.SimpleExample.WPF\RawInput.Sharp.SimpleExample.WPF.csproj", "{63B773C2-7995-4A6A-AAE8-C0DEF73454F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RawInput.Sharp.DigitizerExample", "RawInput.Sharp.DigitizerExample\RawInput.Sharp.DigitizerExample.csproj", "{59C646E7-8E08-4B06-9F2E-B66962448BA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RawInput.Sharp.SimpleExample.Win32", "RawInput.Sharp.SimpleExample.Win32\RawInput.Sharp.SimpleExample.Win32.csproj", "{E3FBC4E2-70F1-447A-980B-0351E9D525A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{47C40BEA-5191-46A3-BE27-4B7A1B725C31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47C40BEA-5191-46A3-BE27-4B7A1B725C31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47C40BEA-5191-46A3-BE27-4B7A1B725C31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47C40BEA-5191-46A3-BE27-4B7A1B725C31}.Release|Any CPU.Build.0 = Release|Any CPU
{F129A5A1-95EA-41CF-98E3-ECB61BEB5040}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F129A5A1-95EA-41CF-98E3-ECB61BEB5040}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F129A5A1-95EA-41CF-98E3-ECB61BEB5040}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F129A5A1-95EA-41CF-98E3-ECB61BEB5040}.Release|Any CPU.Build.0 = Release|Any CPU
{63B773C2-7995-4A6A-AAE8-C0DEF73454F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63B773C2-7995-4A6A-AAE8-C0DEF73454F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63B773C2-7995-4A6A-AAE8-C0DEF73454F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63B773C2-7995-4A6A-AAE8-C0DEF73454F9}.Release|Any CPU.Build.0 = Release|Any CPU
{59C646E7-8E08-4B06-9F2E-B66962448BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{59C646E7-8E08-4B06-9F2E-B66962448BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{59C646E7-8E08-4B06-9F2E-B66962448BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{59C646E7-8E08-4B06-9F2E-B66962448BA2}.Release|Any CPU.Build.0 = Release|Any CPU
{E3FBC4E2-70F1-447A-980B-0351E9D525A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E3FBC4E2-70F1-447A-980B-0351E9D525A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E3FBC4E2-70F1-447A-980B-0351E9D525A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E3FBC4E2-70F1-447A-980B-0351E9D525A7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {12746CE4-3274-4D3F-A053-FBC6E4D452A4}
EndGlobalSection
EndGlobal
================================================
FILE: renovate.json
================================================
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]
}
gitextract_swu12hhg/ ├── .gitattributes ├── .github/ │ └── FUNDING.yml ├── .gitignore ├── LICENSE.txt ├── README.md ├── RawInput.Sharp/ │ ├── EnvironmentEx.cs │ ├── HidButton.cs │ ├── HidButtonSet.cs │ ├── HidButtonSetState.cs │ ├── HidButtonState.cs │ ├── HidPreparsedByteArrayData.cs │ ├── HidReader.cs │ ├── HidUsageAndPage.cs │ ├── HidValue.cs │ ├── HidValueSet.cs │ ├── HidValueSetState.cs │ ├── HidValueState.cs │ ├── IHidPreparsedData.cs │ ├── MarshalEx.cs │ ├── Native/ │ │ ├── CfgMgr32.cs │ │ ├── ConfigReturnValue.cs │ │ ├── DeviceInstanceHandle.cs │ │ ├── DevicePropertyKey.cs │ │ ├── HidD.cs │ │ ├── HidDeviceHandle.cs │ │ ├── HidP.cs │ │ ├── HidPButtonCaps.cs │ │ ├── HidPCaps.cs │ │ ├── HidPCapsNotRange.cs │ │ ├── HidPCapsRange.cs │ │ ├── HidPReportType.cs │ │ ├── HidPValueCaps.cs │ │ ├── HidPreparsedData.cs │ │ ├── Kernel32.cs │ │ ├── NtStatus.cs │ │ ├── RawHid.cs │ │ ├── RawInputDeviceHandle.cs │ │ ├── RawInputDeviceInfo.cs │ │ ├── RawInputDeviceInfoBehavior.cs │ │ ├── RawInputDeviceListItem.cs │ │ ├── RawInputHandle.cs │ │ ├── RawInputHeader.cs │ │ ├── RawInputHidInfo.cs │ │ ├── RawInputKeyboardInfo.cs │ │ ├── RawInputMouseInfo.cs │ │ ├── RawKeyboard.cs │ │ ├── RawMouse.cs │ │ ├── User32.cs │ │ └── Win32ErrorException.cs │ ├── RawInput.Sharp.csproj │ ├── RawInputData.cs │ ├── RawInputDevice.cs │ ├── RawInputDeviceFlags.cs │ ├── RawInputDeviceRegistration.cs │ ├── RawInputDeviceType.cs │ ├── RawInputDigitizer.cs │ ├── RawInputDigitizerButton.cs │ ├── RawInputDigitizerContact.cs │ ├── RawInputDigitizerContactKind.cs │ ├── RawInputDigitizerData.cs │ ├── RawInputHid.cs │ ├── RawInputHidData.cs │ ├── RawInputKeyboard.cs │ ├── RawInputKeyboardData.cs │ ├── RawInputMouse.cs │ └── RawInputMouseData.cs ├── RawInput.Sharp.DigitizerExample/ │ ├── MainForm.Designer.cs │ ├── MainForm.cs │ ├── MainForm.resx │ ├── Program.cs │ └── RawInput.Sharp.DigitizerExample.csproj ├── RawInput.Sharp.SimpleExample/ │ ├── Program.cs │ ├── RawInput.Sharp.SimpleExample.csproj │ ├── RawInputEventArgs.cs │ ├── RawInputReceiverWindow.cs │ └── app.config ├── RawInput.Sharp.SimpleExample.WPF/ │ ├── App.xaml │ ├── App.xaml.cs │ ├── AssemblyInfo.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ └── RawInput.Sharp.SimpleExample.WPF.csproj ├── RawInput.Sharp.SimpleExample.Win32/ │ ├── Program.cs │ └── RawInput.Sharp.SimpleExample.Win32.csproj ├── RawInput.Sharp.sln └── renovate.json
SYMBOL INDEX (315 symbols across 68 files)
FILE: RawInput.Sharp.DigitizerExample/MainForm.Designer.cs
class MainForm (line 3) | partial class MainForm
method Dispose (line 14) | protected override void Dispose(bool disposing)
method InitializeComponent (line 30) | private void InitializeComponent()
FILE: RawInput.Sharp.DigitizerExample/MainForm.cs
class MainForm (line 5) | public partial class MainForm : Form
method MainForm (line 7) | public MainForm()
method OnShown (line 12) | protected override void OnShown(EventArgs e)
method WndProc (line 21) | protected override void WndProc(ref Message m)
FILE: RawInput.Sharp.DigitizerExample/Program.cs
class Program (line 3) | static class Program
method Main (line 8) | [STAThread]
FILE: RawInput.Sharp.SimpleExample.WPF/App.xaml.cs
class App (line 14) | public partial class App : Application
FILE: RawInput.Sharp.SimpleExample.WPF/MainWindow.xaml.cs
class MainWindow (line 12) | public partial class MainWindow : Window
method MainWindow (line 14) | public MainWindow()
method MainWindow_SourceInitialized (line 21) | private void MainWindow_SourceInitialized(object? sender, EventArgs e)
method Hook (line 37) | private IntPtr Hook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam...
FILE: RawInput.Sharp.SimpleExample.Win32/Program.cs
type WNDCLASS (line 114) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp.SimpleExample/RawInputEventArgs.cs
class RawInputEventArgs (line 6) | class RawInputEventArgs : EventArgs
method RawInputEventArgs (line 8) | public RawInputEventArgs(RawInputData data)
FILE: RawInput.Sharp.SimpleExample/RawInputReceiverWindow.cs
class RawInputReceiverWindow (line 7) | sealed class RawInputReceiverWindow : NativeWindow
method RawInputReceiverWindow (line 11) | public RawInputReceiverWindow()
method WndProc (line 23) | protected override void WndProc(ref Message m)
FILE: RawInput.Sharp/EnvironmentEx.cs
class EnvironmentEx (line 6) | static class EnvironmentEx
FILE: RawInput.Sharp/HidButton.cs
class HidButton (line 7) | public class HidButton
method HidButton (line 20) | internal HidButton(HidReader reader, HidPButtonCaps buttonCaps, ushort...
method GetState (line 27) | public HidButtonState GetState(ArraySegment<byte> report) =>
method GetState (line 30) | public HidButtonState GetState(byte[] report, int reportLength) =>
method ToString (line 33) | public override string ToString() =>
FILE: RawInput.Sharp/HidButtonSet.cs
class HidButtonSet (line 9) | public class HidButtonSet : IEnumerable<HidButton>
method HidButtonSet (line 28) | internal HidButtonSet(HidReader reader, HidPButtonCaps buttonCaps)
method GetStates (line 34) | public HidButtonSetState GetStates(ArraySegment<byte> report) =>
method GetStates (line 37) | public HidButtonSetState GetStates(byte[] report, int reportLength) =>
method ToString (line 40) | public override string ToString() =>
method GetEnumerator (line 43) | public IEnumerator<HidButton> GetEnumerator()
method GetEnumerator (line 49) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
FILE: RawInput.Sharp/HidButtonSetState.cs
class HidButtonSetState (line 8) | public class HidButtonSetState : IEnumerable<HidButtonState>
method HidButtonSetState (line 24) | internal HidButtonSetState(HidButtonSet buttonSet, byte[] report, int ...
method ToString (line 31) | public override string ToString() =>
method GetEnumerator (line 34) | public IEnumerator<HidButtonState> GetEnumerator()
method GetEnumerator (line 40) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
FILE: RawInput.Sharp/HidButtonState.cs
class HidButtonState (line 6) | public class HidButtonState
method HidButtonState (line 26) | internal HidButtonState(HidButton button, byte[] report, int reportLen...
method ToString (line 33) | public override string ToString() =>
FILE: RawInput.Sharp/HidPreparsedByteArrayData.cs
class HidPreparsedByteArrayData (line 3) | public class HidPreparsedByteArrayData : IHidPreparsedData
method HidPreparsedByteArrayData (line 7) | public HidPreparsedByteArrayData(byte[] preparsedData) => this.prepars...
method GetPinnableReference (line 9) | public ref byte GetPinnableReference() => ref preparsedData[0];
FILE: RawInput.Sharp/HidReader.cs
class HidReader (line 7) | public class HidReader
method HidReader (line 16) | public unsafe HidReader(IHidPreparsedData preparsedData)
FILE: RawInput.Sharp/HidUsageAndPage.cs
type HidUsageAndPage (line 5) | public readonly struct HidUsageAndPage : IEquatable<HidUsageAndPage>
method HidUsageAndPage (line 15) | public HidUsageAndPage(ushort usagePage, ushort usage)
method Equals (line 39) | public bool Equals(HidUsageAndPage other) =>
method Equals (line 42) | public override bool Equals(object? obj) =>
method GetHashCode (line 45) | public override int GetHashCode() =>
method ToString (line 48) | public override string ToString() =>
FILE: RawInput.Sharp/HidValue.cs
class HidValue (line 7) | public class HidValue
method HidValue (line 32) | internal HidValue(HidReader reader, HidPValueCaps valueCaps, ushort us...
method GetValue (line 39) | public HidValueState GetValue(ArraySegment<byte> report) =>
method GetValue (line 42) | public HidValueState GetValue(byte[] report, int reportLength) => new(...
method ToString (line 44) | public override string ToString() =>
FILE: RawInput.Sharp/HidValueSet.cs
class HidValueSet (line 9) | public class HidValueSet : IEnumerable<HidValue>
method HidValueSet (line 30) | internal HidValueSet(HidReader reader, HidPValueCaps valueCaps)
method GetStates (line 36) | public HidValueSetState GetStates(ArraySegment<byte> report) =>
method GetStates (line 39) | public HidValueSetState GetStates(byte[] report, int reportLength) => ...
method ToString (line 41) | public override string ToString() =>
method GetEnumerator (line 44) | public IEnumerator<HidValue> GetEnumerator()
method GetEnumerator (line 50) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
FILE: RawInput.Sharp/HidValueSetState.cs
class HidValueSetState (line 7) | public class HidValueSetState : IEnumerable<HidValueState>
method HidValueSetState (line 18) | internal HidValueSetState(HidValueSet valueSet, byte[] report, int rep...
method ToString (line 25) | public override string ToString() =>
method GetEnumerator (line 28) | public IEnumerator<HidValueState> GetEnumerator()
method GetEnumerator (line 34) | IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
FILE: RawInput.Sharp/HidValueState.cs
class HidValueState (line 6) | public class HidValueState
method HidValueState (line 45) | internal HidValueState(HidValue value, byte[] report, int reportLength)
method ToString (line 52) | public override string ToString() =>
FILE: RawInput.Sharp/IHidPreparsedData.cs
type IHidPreparsedData (line 3) | public interface IHidPreparsedData
method GetPinnableReference (line 5) | ref byte GetPinnableReference();
FILE: RawInput.Sharp/MarshalEx.cs
class MarshalEx (line 5) | static class MarshalEx
method SizeOf (line 8) | public static int SizeOf<T>() => Marshal.SizeOf<T>();
method SizeOf (line 10) | public static int SizeOf<T>() => Marshal.SizeOf(typeof(T));
FILE: RawInput.Sharp/Native/CfgMgr32.cs
class CfgMgr32 (line 6) | public static class CfgMgr32
method CM_Locate_DevNode (line 8) | [DllImport("cfgmgr32", CharSet = CharSet.Unicode)]
method CM_Get_DevNode_Property (line 11) | [DllImport("cfgmgr32", CharSet = CharSet.Unicode)]
type LocateDevNodeFlags (line 17) | [Flags]
method LocateDevNode (line 38) | public static DeviceInstanceHandle LocateDevNode(string devicePath, Lo...
method TryLocateDevNode (line 45) | public static ConfigReturnValue TryLocateDevNode(string devicePath, Lo...
method GetDevNodePropertyString (line 56) | public static string? GetDevNodePropertyString(DeviceInstanceHandle de...
method TryGetDevNodePropertyString (line 63) | public static ConfigReturnValue TryGetDevNodePropertyString(DeviceInst...
method EnsureSuccess (line 96) | static void EnsureSuccess(this ConfigReturnValue result)
FILE: RawInput.Sharp/Native/ConfigReturnValue.cs
type ConfigReturnValue (line 6) | public enum ConfigReturnValue
FILE: RawInput.Sharp/Native/DeviceInstanceHandle.cs
type DeviceInstanceHandle (line 8) | public readonly struct DeviceInstanceHandle : IEquatable<DeviceInstanceH...
method DeviceInstanceHandle (line 14) | DeviceInstanceHandle(IntPtr value) => this.value = value;
method GetRawValue (line 16) | public static IntPtr GetRawValue(DeviceInstanceHandle handle) => handl...
method Equals (line 24) | public bool Equals(DeviceInstanceHandle other) => value.Equals(other.v...
method Equals (line 26) | public override bool Equals(object? obj) =>
method GetHashCode (line 30) | public override int GetHashCode() => value.GetHashCode();
method ToString (line 32) | public override string ToString() => value.ToString();
FILE: RawInput.Sharp/Native/DevicePropertyKey.cs
type DevicePropertyKey (line 9) | [StructLayout(LayoutKind.Sequential)]
method DevicePropertyKey (line 28) | public DevicePropertyKey(uint l, ushort w1, ushort w2, byte b1, byte b...
FILE: RawInput.Sharp/Native/HidD.cs
class HidD (line 7) | public static class HidD
method HidD_GetManufacturerString (line 9) | [DllImport("hid", CharSet = CharSet.Unicode)]
method HidD_GetProductString (line 13) | [DllImport("hid", CharSet = CharSet.Unicode)]
method HidD_GetSerialNumberString (line 17) | [DllImport("hid", CharSet = CharSet.Unicode)]
method HidD_GetPreparsedData (line 21) | [DllImport("hid")]
method HidD_FreePreparsedData (line 25) | [DllImport("hid")]
method OpenDevice (line 29) | public static HidDeviceHandle OpenDevice(string devicePath)
method TryOpenDevice (line 36) | public static bool TryOpenDevice(string devicePath, out HidDeviceHandl...
method CloseDevice (line 52) | public static void CloseDevice(HidDeviceHandle device)
method GetManufacturerString (line 59) | public static string? GetManufacturerString(HidDeviceHandle device)
method GetProductString (line 66) | public static string? GetProductString(HidDeviceHandle device)
method GetSerialNumberString (line 73) | public static string? GetSerialNumberString(HidDeviceHandle device)
method GetPreparsedData (line 80) | public static HidPreparsedData GetPreparsedData(HidDeviceHandle device)
method FreePreparsedData (line 89) | public static void FreePreparsedData(HidPreparsedData preparsedData)
method GetString (line 94) | static string? GetString(IntPtr handle, Func<IntPtr, byte[], uint, boo...
FILE: RawInput.Sharp/Native/HidDeviceHandle.cs
type HidDeviceHandle (line 5) | public readonly struct HidDeviceHandle : IEquatable<HidDeviceHandle>
method HidDeviceHandle (line 11) | HidDeviceHandle(IntPtr value) => this.value = value;
method GetRawValue (line 13) | public static IntPtr GetRawValue(HidDeviceHandle handle) => handle.value;
method Equals (line 21) | public bool Equals(HidDeviceHandle other) => value.Equals(other.value);
method Equals (line 23) | public override bool Equals(object? obj) =>
method GetHashCode (line 27) | public override int GetHashCode() => value.GetHashCode();
method ToString (line 29) | public override string ToString() => value.ToString();
FILE: RawInput.Sharp/Native/HidP.cs
class HidP (line 6) | public static class HidP
method HidP_GetCaps (line 8) | [DllImport("hid")]
method HidP_GetButtonCaps (line 11) | [DllImport("hid")]
method HidP_GetValueCaps (line 14) | [DllImport("hid")]
method HidP_GetUsages (line 17) | [DllImport("hid")]
method HidP_GetUsageValue (line 20) | [DllImport("hid")]
method HidP_GetScaledUsageValue (line 23) | [DllImport("hid")]
method HidP_GetUsageValueArray (line 26) | [DllImport("hid")]
method TryGetCaps (line 29) | public static NtStatus TryGetCaps(IntPtr preparsedData, out HidPCaps c...
method TryGetCaps (line 32) | public static NtStatus TryGetCaps(HidPreparsedData preparsedData, out ...
method GetCaps (line 35) | public static HidPCaps GetCaps(IntPtr preparsedData)
method GetCaps (line 42) | public static HidPCaps GetCaps(HidPreparsedData preparsedData) =>
method TryGetButtonCaps (line 45) | public static NtStatus TryGetButtonCaps(IntPtr preparsedData, HidPRepo...
method TryGetButtonCaps (line 61) | public static NtStatus TryGetButtonCaps(HidPreparsedData preparsedData...
method GetButtonCaps (line 64) | public static HidPButtonCaps[] GetButtonCaps(IntPtr preparsedData, Hid...
method GetButtonCaps (line 71) | public static HidPButtonCaps[] GetButtonCaps(HidPreparsedData preparse...
method TryGetValueCaps (line 74) | public static NtStatus TryGetValueCaps(IntPtr preparsedData, HidPRepor...
method TryGetValueCaps (line 90) | public static NtStatus TryGetValueCaps(HidPreparsedData preparsedData,...
method GetValueCaps (line 93) | public static HidPValueCaps[] GetValueCaps(IntPtr preparsedData, HidPR...
method GetValueCaps (line 100) | public static HidPValueCaps[] GetValueCaps(HidPreparsedData preparsedD...
method TryGetUsages (line 103) | public static NtStatus TryGetUsages(IntPtr preparsedData, HidPReportTy...
method TryGetUsages (line 114) | public static NtStatus TryGetUsages(HidPreparsedData preparsedData, Hi...
method TryGetUsages (line 117) | public static NtStatus TryGetUsages(IntPtr preparsedData, HidPReportTy...
method TryGetUsages (line 120) | public static NtStatus TryGetUsages(HidPreparsedData preparsedData, Hi...
method GetUsages (line 123) | public static ushort[] GetUsages(IntPtr preparsedData, HidPReportType ...
method GetUsages (line 130) | public static ushort[] GetUsages(HidPreparsedData preparsedData, HidPR...
method GetUsages (line 133) | public static ushort[] GetUsages(IntPtr preparsedData, HidPReportType ...
method GetUsages (line 136) | public static ushort[] GetUsages(HidPreparsedData preparsedData, HidPR...
method TryGetUsageValue (line 139) | public static NtStatus TryGetUsageValue(IntPtr preparsedData, HidPRepo...
method TryGetUsageValue (line 142) | public static NtStatus TryGetUsageValue(HidPreparsedData preparsedData...
method TryGetUsageValue (line 145) | public static NtStatus TryGetUsageValue(IntPtr preparsedData, HidPRepo...
method TryGetUsageValue (line 148) | public static NtStatus TryGetUsageValue(HidPreparsedData preparsedData...
method GetUsageValue (line 151) | public static int GetUsageValue(IntPtr preparsedData, HidPReportType r...
method GetUsageValue (line 158) | public static int GetUsageValue(HidPreparsedData preparsedData, HidPRe...
method GetUsageValue (line 161) | public static int GetUsageValue(IntPtr preparsedData, HidPReportType r...
method GetUsageValue (line 164) | public static int GetUsageValue(HidPreparsedData preparsedData, HidPRe...
method TryGetScaledUsageValue (line 167) | public static NtStatus TryGetScaledUsageValue(IntPtr preparsedData, Hi...
method TryGetScaledUsageValue (line 170) | public static NtStatus TryGetScaledUsageValue(HidPreparsedData prepars...
method TryGetScaledUsageValue (line 173) | public static NtStatus TryGetScaledUsageValue(IntPtr preparsedData, Hi...
method TryGetScaledUsageValue (line 176) | public static NtStatus TryGetScaledUsageValue(HidPreparsedData prepars...
method GetScaledUsageValue (line 179) | public static int GetScaledUsageValue(IntPtr preparsedData, HidPReport...
method GetScaledUsageValue (line 186) | public static int GetScaledUsageValue(HidPreparsedData preparsedData, ...
method GetScaledUsageValue (line 189) | public static int GetScaledUsageValue(IntPtr preparsedData, HidPReport...
method GetScaledUsageValue (line 192) | public static int GetScaledUsageValue(HidPreparsedData preparsedData, ...
method TryGetUsageValueArray (line 195) | public static NtStatus TryGetUsageValueArray(IntPtr preparsedData, Hid...
method TryGetUsageValueArray (line 202) | public static NtStatus TryGetUsageValueArray(HidPreparsedData preparse...
method TryGetUsageValueArray (line 205) | public static NtStatus TryGetUsageValueArray(IntPtr preparsedData, Hid...
method TryGetUsageValueArray (line 208) | public static NtStatus TryGetUsageValueArray(HidPreparsedData preparse...
method GetUsageValueArray (line 211) | public static byte[] GetUsageValueArray(IntPtr preparsedData, HidPRepo...
method GetUsageValueArray (line 218) | public static byte[] GetUsageValueArray(HidPreparsedData preparsedData...
method GetUsageValueArray (line 221) | public static byte[] GetUsageValueArray(IntPtr preparsedData, HidPRepo...
method GetUsageValueArray (line 224) | public static byte[] GetUsageValueArray(HidPreparsedData preparsedData...
method EnsureSuccess (line 227) | public static void EnsureSuccess(this NtStatus result)
FILE: RawInput.Sharp/Native/HidPButtonCaps.cs
type HidPButtonCaps (line 8) | [StructLayout(LayoutKind.Explicit)]
FILE: RawInput.Sharp/Native/HidPCaps.cs
type HidPCaps (line 8) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/HidPCapsNotRange.cs
type HidPCapsNotRange (line 5) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/HidPCapsRange.cs
type HidPCapsRange (line 5) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/HidPReportType.cs
type HidPReportType (line 6) | public enum HidPReportType
FILE: RawInput.Sharp/Native/HidPValueCaps.cs
type HidPValueCaps (line 8) | [StructLayout(LayoutKind.Explicit)]
FILE: RawInput.Sharp/Native/HidPreparsedData.cs
type HidPreparsedData (line 8) | public readonly struct HidPreparsedData : IHidPreparsedData, IEquatable<...
method HidPreparsedData (line 14) | HidPreparsedData(IntPtr value)
method Equals (line 27) | public bool Equals(HidPreparsedData other) => value.Equals(other.value);
method Equals (line 29) | public override bool Equals(object? obj) =>
method GetHashCode (line 33) | public override int GetHashCode() => value.GetHashCode();
method ToString (line 35) | public override string ToString() => value.ToString();
method GetPinnableReference (line 37) | public unsafe ref byte GetPinnableReference() => ref *(byte*)value.ToP...
FILE: RawInput.Sharp/Native/Kernel32.cs
class Kernel32 (line 7) | static class Kernel32
method CreateFileCore (line 9) | [DllImport("kernel32", EntryPoint = "CreateFile", SetLastError = true,...
method CloseHandle (line 12) | [DllImport("kernel32", SetLastError = true)]
method GetModuleHandleCore (line 15) | [DllImport("kernel32", EntryPoint = "GetModuleHandle", SetLastError = ...
method GetProcAddressCore (line 18) | [DllImport("kernel32", EntryPoint = "GetProcAddress", SetLastError = t...
method IsWow64ProcessCore (line 21) | [DllImport("kernel32", EntryPoint = "IsWow64Process", SetLastError = t...
method GetCurrentProcess (line 24) | [DllImport("kernel32")]
method FormatMessage (line 27) | [DllImport("kernel32", SetLastError = true)]
type DesiredAccess (line 32) | [Flags]
type ShareMode (line 40) | [Flags]
type CreateDisposition (line 49) | public enum CreateDisposition : uint
method GetModuleHandle (line 58) | public static IntPtr GetModuleHandle(string moduleName)
method GetProcAddress (line 66) | public static IntPtr GetProcAddress(IntPtr hModule, string procName)
method IsWow64Process (line 74) | public static bool IsWow64Process(IntPtr hProcess)
method CreateFile (line 81) | public static IntPtr CreateFile(
method TryCreateFile (line 96) | public static bool TryCreateFile(
method FormatMessage (line 111) | public static string FormatMessage(int errorCode)
FILE: RawInput.Sharp/Native/NtStatus.cs
type NtStatus (line 6) | public enum NtStatus : uint
FILE: RawInput.Sharp/Native/RawHid.cs
type RawHid (line 10) | public struct RawHid
method FromPointer (line 20) | public static unsafe RawHid FromPointer(void* ptr)
method ToHidReports (line 33) | public ArraySegment<byte>[] ToHidReports()
method ToStructure (line 43) | public unsafe byte[] ToStructure()
method ToString (line 60) | public override string ToString() =>
FILE: RawInput.Sharp/Native/RawInputDeviceHandle.cs
type RawInputDeviceHandle (line 8) | public readonly struct RawInputDeviceHandle : IEquatable<RawInputDeviceH...
method RawInputDeviceHandle (line 14) | RawInputDeviceHandle(IntPtr value) => this.value = value;
method GetRawValue (line 16) | public static IntPtr GetRawValue(RawInputDeviceHandle handle) => handl...
method Equals (line 24) | public bool Equals(RawInputDeviceHandle other) => value.Equals(other.v...
method Equals (line 26) | public override bool Equals(object? obj) =>
method GetHashCode (line 30) | public override int GetHashCode() => value.GetHashCode();
method ToString (line 32) | public override string ToString() => value.ToString();
FILE: RawInput.Sharp/Native/RawInputDeviceInfo.cs
type RawInputDeviceInfo (line 8) | [StructLayout(LayoutKind.Explicit)]
FILE: RawInput.Sharp/Native/RawInputDeviceInfoBehavior.cs
type RawInputDeviceInfoBehavior (line 6) | public enum RawInputDeviceInfoBehavior : uint
FILE: RawInput.Sharp/Native/RawInputDeviceListItem.cs
type RawInputDeviceListItem (line 6) | public struct RawInputDeviceListItem
FILE: RawInput.Sharp/Native/RawInputHandle.cs
type RawInputHandle (line 8) | public readonly struct RawInputHandle : IEquatable<RawInputHandle>
method RawInputHandle (line 14) | RawInputHandle(IntPtr value) => this.value = value;
method GetRawValue (line 16) | public static IntPtr GetRawValue(RawInputHandle handle) => handle.value;
method Equals (line 24) | public bool Equals(RawInputHandle other) => value.Equals(other.value);
method Equals (line 26) | public override bool Equals(object? obj) =>
method GetHashCode (line 30) | public override int GetHashCode() => value.GetHashCode();
method ToString (line 32) | public override string ToString() => value.ToString();
FILE: RawInput.Sharp/Native/RawInputHeader.cs
type RawInputHeader (line 9) | [StructLayout(LayoutKind.Sequential)]
method ToString (line 22) | public override string ToString() =>
FILE: RawInput.Sharp/Native/RawInputHidInfo.cs
type RawInputHidInfo (line 8) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/RawInputKeyboardInfo.cs
type RawInputKeyboardInfo (line 8) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/RawInputMouseInfo.cs
type RawInputMouseInfo (line 8) | [StructLayout(LayoutKind.Sequential)]
FILE: RawInput.Sharp/Native/RawKeyboard.cs
type RawKeyboard (line 9) | [StructLayout(LayoutKind.Sequential)]
method ToString (line 25) | public override string ToString() =>
type RawKeyboardFlags (line 32) | [Flags]
FILE: RawInput.Sharp/Native/RawMouse.cs
type RawMouse (line 9) | [StructLayout(LayoutKind.Sequential)]
method ToString (line 29) | public override string ToString() =>
type RawMouseFlags (line 36) | [Flags]
type RawMouseButtonFlags (line 60) | [Flags]
FILE: RawInput.Sharp/Native/User32.cs
method GetRawInputDeviceList (line 9) | [DllImport("user32", SetLastError = true)]
method GetRawInputDeviceInfo (line 12) | [DllImport("user32", SetLastError = true)]
method GetRawInputDeviceInfo (line 15) | [DllImport("user32", SetLastError = true, CharSet = CharSet.Unicode)]
method GetRawInputDeviceInfo (line 18) | [DllImport("user32", SetLastError = true)]
method GetRawInputDeviceInfo (line 21) | [DllImport("user32", SetLastError = true)]
method RegisterRawInputDevices (line 24) | [DllImport("user32", SetLastError = true)]
method GetRegisteredRawInputDevices (line 27) | [DllImport("user32", SetLastError = true)]
method GetRawInputData (line 30) | [DllImport("user32", SetLastError = true)]
method GetRawInputData (line 34) | [DllImport("user32", SetLastError = true)]
method GetRawInputBuffer (line 37) | [DllImport("user32", SetLastError = true)]
method DefRawInputProc (line 40) | [DllImport("user32", SetLastError = true)]
type RawInputGetBehavior (line 43) | public enum RawInputGetBehavior : uint
method GetRawInputDeviceList (line 49) | public static RawInputDeviceListItem[] GetRawInputDeviceList()
method GetRawInputDeviceName (line 64) | public static string? GetRawInputDeviceName(RawInputDeviceHandle device)
method GetRawInputDeviceInfo (line 80) | public static RawInputDeviceInfo GetRawInputDeviceInfo(RawInputDeviceHan...
method GetRawInputDevicePreparsedData (line 90) | public static byte[] GetRawInputDevicePreparsedData(RawInputDeviceHandle...
method RegisterRawInputDevices (line 104) | public static void RegisterRawInputDevices(params RawInputDeviceRegistra...
method GetRegisteredRawInputDevices (line 109) | public static RawInputDeviceRegistration[] GetRegisteredRawInputDevices()
method GetRawInputDataHeader (line 122) | public static RawInputHeader GetRawInputDataHeader(RawInputHandle rawInput)
method GetRawInputDataSize (line 133) | public static uint GetRawInputDataSize(RawInputHandle rawInput)
method GetRawInputData (line 144) | public static void GetRawInputData(RawInputHandle rawInput, IntPtr ptr, ...
FILE: RawInput.Sharp/Native/Win32ErrorException.cs
class Win32ErrorException (line 6) | public class Win32ErrorException : Exception
method Win32ErrorException (line 8) | public Win32ErrorException()
method Win32ErrorException (line 13) | public Win32ErrorException(int win32ErrorCode)
FILE: RawInput.Sharp/RawInputData.cs
class RawInputData (line 7) | public abstract class RawInputData
method RawInputData (line 18) | protected RawInputData(RawInputHeader header)
method FromHandle (line 23) | public static RawInputData FromHandle(IntPtr lParam)
method FromHandle (line 26) | public static RawInputData FromHandle(RawInputHandle rawInput)
method ParseRawInputBufferItem (line 43) | static unsafe RawInputData ParseRawInputBufferItem(byte* ptr)
method Align (line 92) | protected static int Align(int x) => (x + IntPtr.Size - 1) & ~(IntPtr....
method DefRawInputProc (line 94) | public static void DefRawInputProc(RawInputData[] data) =>
method ToStructure (line 97) | public abstract byte[] ToStructure();
FILE: RawInput.Sharp/RawInputDevice.cs
class RawInputDevice (line 7) | public abstract class RawInputDevice
method GetAttributesOnce (line 54) | void GetAttributesOnce()
method GetAttributesFromHidD (line 64) | void GetAttributesFromHidD()
method GetAttributesFromCfgMgr (line 80) | void GetAttributesFromCfgMgr()
method RawInputDevice (line 94) | protected RawInputDevice(RawInputDeviceHandle device, RawInputDeviceIn...
method FromHandle (line 101) | public static RawInputDevice FromHandle(RawInputDeviceHandle device)
method GetDevices (line 124) | public static RawInputDevice[] GetDevices()
method GetPreparsedData (line 131) | public byte[] GetPreparsedData() =>
method RegisterDevice (line 134) | public static void RegisterDevice(HidUsageAndPage usageAndPage, RawInp...
method RegisterDevice (line 137) | public static void RegisterDevice(params RawInputDeviceRegistration[] ...
method UnregisterDevice (line 140) | public static void UnregisterDevice(HidUsageAndPage usageAndPage) =>
method GetRegisteredDevices (line 143) | public static RawInputDeviceRegistration[] GetRegisteredDevices() =>
FILE: RawInput.Sharp/RawInputDeviceFlags.cs
type RawInputDeviceFlags (line 8) | [Flags]
FILE: RawInput.Sharp/RawInputDeviceRegistration.cs
type RawInputDeviceRegistration (line 5) | public readonly struct RawInputDeviceRegistration
method RawInputDeviceRegistration (line 17) | public RawInputDeviceRegistration(HidUsageAndPage usageAndPage, RawInp...
method RawInputDeviceRegistration (line 22) | public RawInputDeviceRegistration(ushort usagePage, ushort usage, RawI...
FILE: RawInput.Sharp/RawInputDeviceType.cs
type RawInputDeviceType (line 3) | public enum RawInputDeviceType
FILE: RawInput.Sharp/RawInputDigitizer.cs
class RawInputDigitizer (line 7) | public class RawInputDigitizer : RawInputHid
method RawInputDigitizer (line 13) | internal RawInputDigitizer(RawInputDeviceHandle device, RawInputDevice...
method IsSupported (line 19) | public static bool IsSupported(HidUsageAndPage usageAndPage) =>
FILE: RawInput.Sharp/RawInputDigitizerButton.cs
class RawInputDigitizerButton (line 6) | class RawInputDigitizerButton
method RawInputDigitizerButton (line 22) | RawInputDigitizerButton(bool? inRange, bool? isInverted, bool isDown, ...
method Read (line 32) | internal static IEnumerable<RawInputDigitizerButton> Read(
FILE: RawInput.Sharp/RawInputDigitizerContact.cs
class RawInputDigitizerContact (line 6) | public class RawInputDigitizerContact
method RawInputDigitizerContact (line 48) | RawInputDigitizerContact(
method Read (line 71) | internal static IEnumerable<RawInputDigitizerContact> Read(
method ToString (line 114) | public override string ToString() =>
FILE: RawInput.Sharp/RawInputDigitizerContactKind.cs
type RawInputDigitizerContactKind (line 3) | public enum RawInputDigitizerContactKind
FILE: RawInput.Sharp/RawInputDigitizerData.cs
class RawInputDigitizerData (line 8) | public class RawInputDigitizerData : RawInputHidData
method RawInputDigitizerData (line 16) | public RawInputDigitizerData(RawInputHeader header, RawHid hid)
FILE: RawInput.Sharp/RawInputHid.cs
class RawInputHid (line 6) | public class RawInputHid : RawInputDevice
method RawInputHid (line 20) | internal RawInputHid(RawInputDeviceHandle device, RawInputDeviceInfo d...
FILE: RawInput.Sharp/RawInputHidData.cs
class RawInputHidData (line 6) | public class RawInputHidData : RawInputData
method RawInputHidData (line 22) | protected RawInputHidData(RawInputHeader header, RawHid hid)
method Create (line 26) | public static RawInputHidData Create(RawInputHeader header, RawHid hid)
method ToStructure (line 36) | public override unsafe byte[] ToStructure()
method ToString (line 50) | public override string ToString() =>
FILE: RawInput.Sharp/RawInputKeyboard.cs
class RawInputKeyboard (line 7) | public class RawInputKeyboard : RawInputDevice
method RawInputKeyboard (line 28) | internal RawInputKeyboard(RawInputDeviceHandle device, RawInputDeviceI...
FILE: RawInput.Sharp/RawInputKeyboardData.cs
class RawInputKeyboardData (line 6) | public class RawInputKeyboardData : RawInputData
method RawInputKeyboardData (line 10) | public RawInputKeyboardData(RawInputHeader header, RawKeyboard keyboard)
method ToStructure (line 14) | public override unsafe byte[] ToStructure()
FILE: RawInput.Sharp/RawInputMouse.cs
class RawInputMouse (line 7) | public class RawInputMouse : RawInputDevice
method RawInputMouse (line 26) | internal RawInputMouse(RawInputDeviceHandle device, RawInputDeviceInfo...
FILE: RawInput.Sharp/RawInputMouseData.cs
class RawInputMouseData (line 6) | public class RawInputMouseData : RawInputData
method RawInputMouseData (line 10) | public RawInputMouseData(RawInputHeader header, RawMouse mouse)
method ToStructure (line 14) | public override unsafe byte[] ToStructure()
Condensed preview — 86 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (145K chars).
[
{
"path": ".gitattributes",
"chars": 2518,
"preview": "###############################################################################\n# Set default behavior to automatically "
},
{
"path": ".github/FUNDING.yml",
"chars": 18,
"preview": "github: [mfakane]\n"
},
{
"path": ".gitignore",
"chars": 4305,
"preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
},
{
"path": "LICENSE.txt",
"chars": 874,
"preview": "The zlib License\n\nCopyright (c) 2019 mfakane\n\nThis software is provided 'as-is', without any express or implied warrant"
},
{
"path": "README.md",
"chars": 2186,
"preview": "# RawInput.Sharp\n\nA simple wrapper library for Windows [Raw Input](https://learn.microsoft.com/en-us/windows/win32/inpu"
},
{
"path": "RawInput.Sharp/EnvironmentEx.cs",
"chars": 527,
"preview": "using System;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\nstatic class Environme"
},
{
"path": "RawInput.Sharp/HidButton.cs",
"chars": 1098,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/HidButtonSet.cs",
"chars": 1636,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Linearstar.Windows.R"
},
{
"path": "RawInput.Sharp/HidButtonSetState.cs",
"chars": 1286,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing Linearstar.Windows.RawInput.Native;\n\nna"
},
{
"path": "RawInput.Sharp/HidButtonState.cs",
"chars": 910,
"preview": "using System;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic class HidButton"
},
{
"path": "RawInput.Sharp/HidPreparsedByteArrayData.cs",
"chars": 306,
"preview": "namespace Linearstar.Windows.RawInput;\n\npublic class HidPreparsedByteArrayData : IHidPreparsedData\n{\n readonly byte["
},
{
"path": "RawInput.Sharp/HidReader.cs",
"chars": 981,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/HidUsageAndPage.cs",
"chars": 1506,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic readonly struct HidUsageAndPage : IEquatable<HidUsageAndP"
},
{
"path": "RawInput.Sharp/HidValue.cs",
"chars": 1396,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/HidValueSet.cs",
"chars": 1655,
"preview": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Linearstar.Windows.R"
},
{
"path": "RawInput.Sharp/HidValueSetState.cs",
"chars": 1109,
"preview": "using System.Collections;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace Linearstar.Windows.RawInput;\n"
},
{
"path": "RawInput.Sharp/HidValueState.cs",
"chars": 1462,
"preview": "using System;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic class HidValueS"
},
{
"path": "RawInput.Sharp/IHidPreparsedData.cs",
"chars": 116,
"preview": "namespace Linearstar.Windows.RawInput;\n\npublic interface IHidPreparsedData\n{\n ref byte GetPinnableReference();\n}"
},
{
"path": "RawInput.Sharp/MarshalEx.cs",
"chars": 263,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput;\n\nstatic class MarshalEx\n{\n#if NET7_0_OR_G"
},
{
"path": "RawInput.Sharp/Native/CfgMgr32.cs",
"chars": 3178,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\npublic static class"
},
{
"path": "RawInput.Sharp/Native/ConfigReturnValue.cs",
"chars": 1828,
"preview": "namespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// CONFIGRET\n/// </summary>\npublic enum ConfigReturnValue"
},
{
"path": "RawInput.Sharp/Native/DeviceInstanceHandle.cs",
"chars": 1054,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// DEVINST\n/// </summary>\npublic readonly "
},
{
"path": "RawInput.Sharp/Native/DevicePropertyKey.cs",
"chars": 1184,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// D"
},
{
"path": "RawInput.Sharp/Native/HidD.cs",
"chars": 3415,
"preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n"
},
{
"path": "RawInput.Sharp/Native/HidDeviceHandle.cs",
"chars": 947,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\npublic readonly struct HidDeviceHandle : IEquatable<HidDe"
},
{
"path": "RawInput.Sharp/Native/HidP.cs",
"chars": 16165,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\npublic static class"
},
{
"path": "RawInput.Sharp/Native/HidPButtonCaps.cs",
"chars": 1128,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HIDP_BUTTON_CAP"
},
{
"path": "RawInput.Sharp/Native/HidPCaps.cs",
"chars": 958,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HIDP_CAPS\n/// <"
},
{
"path": "RawInput.Sharp/Native/HidPCapsNotRange.cs",
"chars": 403,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n[StructLayout(LayoutKind.Sequenti"
},
{
"path": "RawInput.Sharp/Native/HidPCapsRange.cs",
"chars": 400,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n[StructLayout(LayoutKind.Sequenti"
},
{
"path": "RawInput.Sharp/Native/HidPReportType.cs",
"chars": 176,
"preview": "namespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HIDP_REPORT_TYPE\n/// </summary>\npublic enum HidPReport"
},
{
"path": "RawInput.Sharp/Native/HidPValueCaps.cs",
"chars": 1492,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HIDP_VALUE_CAPS"
},
{
"path": "RawInput.Sharp/Native/HidPreparsedData.cs",
"chars": 1154,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HIDP_PREPARSED_DATA\n/// </summary>\npubl"
},
{
"path": "RawInput.Sharp/Native/Kernel32.cs",
"chars": 4001,
"preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n"
},
{
"path": "RawInput.Sharp/Native/NtStatus.cs",
"chars": 765,
"preview": "namespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// NTSTATUS\n/// </summary>\npublic enum NtStatus : uint\n{\n"
},
{
"path": "RawInput.Sharp/Native/RawHid.cs",
"chars": 1605,
"preview": "using System;\nusing System.Linq;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n"
},
{
"path": "RawInput.Sharp/Native/RawInputDeviceHandle.cs",
"chars": 1052,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HANDLE\n/// </summary>\npublic readonly s"
},
{
"path": "RawInput.Sharp/Native/RawInputDeviceInfo.cs",
"chars": 905,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RID_DEVICE_INFO"
},
{
"path": "RawInput.Sharp/Native/RawInputDeviceInfoBehavior.cs",
"chars": 413,
"preview": "namespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RIDI_*\n/// </summary>\npublic enum RawInputDeviceInfoBe"
},
{
"path": "RawInput.Sharp/Native/RawInputDeviceListItem.cs",
"chars": 348,
"preview": "namespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RAWINPUTDEVICELIST\n/// </summary>\npublic struct RawInp"
},
{
"path": "RawInput.Sharp/Native/RawInputHandle.cs",
"chars": 977,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// HRAWINPUT\n/// </summary>\npublic readonl"
},
{
"path": "RawInput.Sharp/Native/RawInputHeader.cs",
"chars": 634,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// R"
},
{
"path": "RawInput.Sharp/Native/RawInputHidInfo.cs",
"chars": 818,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RID_DEVICE_INFO"
},
{
"path": "RawInput.Sharp/Native/RawInputKeyboardInfo.cs",
"chars": 1104,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RID_DEVICE_INFO"
},
{
"path": "RawInput.Sharp/Native/RawInputMouseInfo.cs",
"chars": 815,
"preview": "using System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// RID_DEVICE_INFO"
},
{
"path": "RawInput.Sharp/Native/RawKeyboard.cs",
"chars": 1132,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// R"
},
{
"path": "RawInput.Sharp/Native/RawMouse.cs",
"chars": 2630,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n/// <summary>\n/// R"
},
{
"path": "RawInput.Sharp/Native/User32.cs",
"chars": 8578,
"preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\n"
},
{
"path": "RawInput.Sharp/Native/Win32ErrorException.cs",
"chars": 357,
"preview": "using System;\nusing System.Runtime.InteropServices;\n\nnamespace Linearstar.Windows.RawInput.Native;\n\npublic class Win32E"
},
{
"path": "RawInput.Sharp/RawInput.Sharp.csproj",
"chars": 915,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <LangVersion>10</LangVersion>\n <RootNamespace>Linearstar.Wi"
},
{
"path": "RawInput.Sharp/RawInputData.cs",
"chars": 3350,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/RawInputDevice.cs",
"chars": 4813,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/RawInputDeviceFlags.cs",
"chars": 2216,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput;\n\n/// <summary>\n/// RIDEV_*\n/// </summary>\n[Flags]\npublic enum Raw"
},
{
"path": "RawInput.Sharp/RawInputDeviceRegistration.cs",
"chars": 869,
"preview": "using System;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic readonly struct RawInputDeviceRegistration\n{\n readonly"
},
{
"path": "RawInput.Sharp/RawInputDeviceType.cs",
"chars": 109,
"preview": "namespace Linearstar.Windows.RawInput;\n\npublic enum RawInputDeviceType\n{\n Mouse,\n Keyboard,\n Hid,\n}"
},
{
"path": "RawInput.Sharp/RawInputDigitizer.cs",
"chars": 866,
"preview": "using System;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npub"
},
{
"path": "RawInput.Sharp/RawInputDigitizerButton.cs",
"chars": 2232,
"preview": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace Linearstar.Windows.RawInput;\n\nclass RawInputDigitizerBu"
},
{
"path": "RawInput.Sharp/RawInputDigitizerContact.cs",
"chars": 4228,
"preview": "using System.Collections.Generic;\nusing System.Linq;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic class RawInputDigi"
},
{
"path": "RawInput.Sharp/RawInputDigitizerContactKind.cs",
"chars": 139,
"preview": "namespace Linearstar.Windows.RawInput;\n\npublic enum RawInputDigitizerContactKind\n{\n None,\n Finger,\n Hover,\n "
},
{
"path": "RawInput.Sharp/RawInputDigitizerData.cs",
"chars": 2135,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace"
},
{
"path": "RawInput.Sharp/RawInputHid.cs",
"chars": 898,
"preview": "using System;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic class RawInputH"
},
{
"path": "RawInput.Sharp/RawInputHidData.cs",
"chars": 1696,
"preview": "using System.Linq;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;\n\npublic class RawI"
},
{
"path": "RawInput.Sharp/RawInputKeyboard.cs",
"chars": 1427,
"preview": "using System;\nusing System.Globalization;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawIn"
},
{
"path": "RawInput.Sharp/RawInputKeyboardData.cs",
"chars": 855,
"preview": "using System.Runtime.InteropServices;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;"
},
{
"path": "RawInput.Sharp/RawInputMouse.cs",
"chars": 1238,
"preview": "using System;\nusing System.Globalization;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawIn"
},
{
"path": "RawInput.Sharp/RawInputMouseData.cs",
"chars": 819,
"preview": "using System.Runtime.InteropServices;\nusing Linearstar.Windows.RawInput.Native;\n\nnamespace Linearstar.Windows.RawInput;"
},
{
"path": "RawInput.Sharp.DigitizerExample/MainForm.Designer.cs",
"chars": 1932,
"preview": "namespace RawInput.Sharp.DigitizerExample;\n\npartial class MainForm\n{\n /// <summary>\n /// Required designer varia"
},
{
"path": "RawInput.Sharp.DigitizerExample/MainForm.cs",
"chars": 1192,
"preview": "using Linearstar.Windows.RawInput;\n\nnamespace RawInput.Sharp.DigitizerExample;\n\npublic partial class MainForm : Form\n{\n "
},
{
"path": "RawInput.Sharp.DigitizerExample/MainForm.resx",
"chars": 2755,
"preview": "<root>\n <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsof"
},
{
"path": "RawInput.Sharp.DigitizerExample/Program.cs",
"chars": 448,
"preview": "namespace RawInput.Sharp.DigitizerExample;\n\nstatic class Program\n{\n /// <summary>\n /// The main entry point for t"
},
{
"path": "RawInput.Sharp.DigitizerExample/RawInput.Sharp.DigitizerExample.csproj",
"chars": 429,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>WinExe</OutputType>\n <TargetFramework"
},
{
"path": "RawInput.Sharp.SimpleExample/Program.cs",
"chars": 1235,
"preview": "using System;\nusing System.Linq;\nusing System.Windows.Forms;\nusing Linearstar.Windows.RawInput;\nusing RawInput.Sharp.Si"
},
{
"path": "RawInput.Sharp.SimpleExample/RawInput.Sharp.SimpleExample.csproj",
"chars": 404,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n <PropertyGroup>\n <TargetFramework>net6.0-windows</TargetFramework>\n <OutputTy"
},
{
"path": "RawInput.Sharp.SimpleExample/RawInputEventArgs.cs",
"chars": 251,
"preview": "using System;\nusing Linearstar.Windows.RawInput;\n\nnamespace RawInput.Sharp.SimpleExample;\n\nclass RawInputEventArgs : Ev"
},
{
"path": "RawInput.Sharp.SimpleExample/RawInputReceiverWindow.cs",
"chars": 759,
"preview": "using System;\nusing System.Windows.Forms;\nusing Linearstar.Windows.RawInput;\n\nnamespace RawInput.Sharp.SimpleExample;\n\n"
},
{
"path": "RawInput.Sharp.SimpleExample/app.config",
"chars": 158,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n<startup><supportedRuntime version=\"v4.0\" sku=\".NETFramework,Vers"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/App.xaml",
"chars": 407,
"preview": "<Application x:Class=\"RawInput.Sharp.SimpleExample.WPF.App\"\n xmlns=\"http://schemas.microsoft.com/winfx/2006"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/App.xaml.cs",
"chars": 346,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Configuration;\nusing System.Data;\nusing System.Linq;\nusing"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/AssemblyInfo.cs",
"chars": 595,
"preview": "using System.Windows;\n\n[assembly: ThemeInfo(\n ResourceDictionaryLocation.None, //where theme specific resource dictio"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/MainWindow.xaml",
"chars": 529,
"preview": "<Window x:Class=\"RawInput.Sharp.SimpleExample.WPF.MainWindow\"\n xmlns=\"http://schemas.microsoft.com/winfx/2006/xa"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/MainWindow.xaml.cs",
"chars": 2495,
"preview": "using System;\nusing System.Diagnostics;\nusing System.Windows;\nusing System.Windows.Interop;\nusing Linearstar.Windows.Ra"
},
{
"path": "RawInput.Sharp.SimpleExample.WPF/RawInput.Sharp.SimpleExample.WPF.csproj",
"chars": 346,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>WinExe</OutputType>\n <TargetFramework"
},
{
"path": "RawInput.Sharp.SimpleExample.Win32/Program.cs",
"chars": 3856,
"preview": "using Linearstar.Windows.RawInput;\nusing System.ComponentModel;\nusing System.Runtime.InteropServices;\n\n\nvar WindowClass"
},
{
"path": "RawInput.Sharp.SimpleExample.Win32/RawInput.Sharp.SimpleExample.Win32.csproj",
"chars": 445,
"preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n <PropertyGroup>\n <OutputType>Exe</OutputType>\n <TargetFramework>net8.0-windo"
},
{
"path": "RawInput.Sharp.sln",
"chars": 3543,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.7.3392"
},
{
"path": "renovate.json",
"chars": 107,
"preview": "{\n \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n \"extends\": [\n \"config:base\"\n ]\n}\n"
}
]
About this extraction
This page contains the full source code of the mfakane/rawinput-sharp GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 86 files (131.6 KB), approximately 35.6k tokens, and a symbol index with 315 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.