private void AddValueCap(ValueCaps cap, string preText) { ValueCapEntry entry = new ValueCapEntry(); entry.Value = new ValueCapsWrapper(cap); entry.Text = preText + " " + cap.ReportID.ToString("X2") + " / Usage Page " + cap.UsagePage.ToString("X4"); listBoxValueCaps.Items.Add(entry); }
public ValueCapsWrapper(ValueCaps caps) { this.UsagePage = caps.UsagePage; this.ReportID = caps.ReportID; this.IsAlias = caps.IsAlias; this.BitField = caps.BitField; this.LinkCollection = caps.LinkCollection; this.LinkUsage = caps.LinkUsage; this.LinkUsagePage = caps.LinkUsagePage; this.IsRange = caps.IsRange; this.IsStringRange = caps.IsStringRange; this.IsDesignatorRange = caps.IsDesignatorRange; this.IsAbsolute = caps.IsAbsolute; this.HasNull = caps.HasNull; this.Reserved = caps.Reserved; this.BitSize = caps.BitSize; this.ReportCount = caps.ReportCount; this.Reserved2 = caps.Reserved2; this.UnitsExp = caps.UnitsExp; this.Units = caps.Units; this.LogicalMin = caps.LogicalMin; this.LogicalMax = caps.LogicalMax; this.PhysicalMin = caps.PhysicalMin; this.PhysicalMax = caps.PhysicalMax; this.RangeUnion = new CapsRangeUnionWrapper(); RangeUnion.Range = new CapsRangeWrapper(); RangeUnion.Range.UsageMin = caps.RangeUnion.Range.UsageMin; RangeUnion.Range.UsageMax = caps.RangeUnion.Range.UsageMax; RangeUnion.Range.StringMin = caps.RangeUnion.Range.StringMin; RangeUnion.Range.StringMax = caps.RangeUnion.Range.StringMax; RangeUnion.Range.DesignatorMin = caps.RangeUnion.Range.DesignatorMin; RangeUnion.Range.DesignatorMax = caps.RangeUnion.Range.DesignatorMax; RangeUnion.Range.DataIndexMin = caps.RangeUnion.Range.DataIndexMin; RangeUnion.Range.DataIndexMax = caps.RangeUnion.Range.DataIndexMax; RangeUnion.NotRange = new CapsNotRangeWrapper(); RangeUnion.NotRange.Usage = caps.RangeUnion.NotRange.Usage; RangeUnion.NotRange.Reserved1 = caps.RangeUnion.NotRange.Reserved1; RangeUnion.NotRange.StringIndex = caps.RangeUnion.NotRange.StringIndex; RangeUnion.NotRange.Reserved2 = caps.RangeUnion.NotRange.Reserved2; RangeUnion.NotRange.DesignatorIndex = caps.RangeUnion.NotRange.DesignatorIndex; RangeUnion.NotRange.Reserved3 = caps.RangeUnion.NotRange.Reserved3; RangeUnion.NotRange.DataIndex = caps.RangeUnion.NotRange.DataIndex; RangeUnion.NotRange.Reserved4 = caps.RangeUnion.NotRange.Reserved4; }
public int GetReportLength(ReportType type, byte reportId) { int bitLength = 0; List <ValueCaps> caps = null; switch (type) { case ReportType.Input: caps = inputValueCaps; break; case ReportType.Output: caps = outputValueCaps; break; case ReportType.Feature: caps = featureValueCaps; break; } if (caps == null) { return(0); } for (int i = 0; i < caps.Count; i++) { ValueCaps c = caps[i]; if (c.ReportID == reportId) { bitLength += c.ReportCount * c.BitSize; } } return(bitLength / 8); }
/// <summary> /// Determines whether the axis is supported. /// </summary> /// <param name="caps">The HID value caps.</param> /// <returns>True if the axis is supported, otherwise false.</returns> private static bool IsSupported(ref ValueCaps caps) { if (caps.IsRange) { return false; } switch (caps.UsagePage) { case UsagePage.Generic: switch (caps.Single.Usage) { case Usage.HatSwitch: case Usage.X: case Usage.Y: case Usage.Z: case Usage.Rx: case Usage.Ry: case Usage.Rz: case Usage.Dial: case Usage.Wheel: case Usage.Slider: return true; } break; case UsagePage.Simulation: switch (caps.Single.Usage) { case Usage.Rudder: case Usage.Throttle: return true; } break; } return false; }
/// <summary> /// Creates the axis information for the device. /// </summary> /// <param name="deviceData">The device data.</param> /// <returns>The axis information.</returns> public static unsafe DeviceAxis[] Create(void* deviceData) { Caps caps; GetCaps(deviceData, out caps); var list = new List<DeviceAxis>(); var count = caps.NumberInputValueCaps; var array = new ValueCaps[count]; if (GetValueCaps(ReportType.Input, array, ref count, deviceData) == Result.SUCCESS) { for (var i = 0; i < array.Length; i++) { if (IsSupported(ref array[i])) { list.Add(new DeviceAxis(ref array[i])); } } } return list.ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="DeviceAxis"/> class. /// </summary> /// <param name="caps">The HID value caps.</param> private DeviceAxis(ref ValueCaps caps) { this.usage = caps.Single.Usage; this.usagePage = caps.UsagePage; this.linkCollection = caps.LinkCollection; this.minimumValue = caps.LogicalMin; this.maximumValue = caps.LogicalMax; switch (this.usagePage) { case UsagePage.Generic: switch (this.usage) { case Usage.X: this.Name = "X axis"; this.Type = AxisType.X; break; case Usage.Y: this.Name = "Y axis"; this.Type = AxisType.Y; break; case Usage.Z: this.Name = "Z axis"; this.Type = AxisType.Z; break; case Usage.Rx: this.Name = "RX axis"; this.Type = AxisType.Rx; break; case Usage.Ry: this.Name = "RY axis"; this.Type = AxisType.Ry; break; case Usage.Rz: this.Name = "RZ axis"; this.Type = AxisType.Rz; break; case Usage.Dial: this.Name = "Dial"; this.Type = AxisType.Dial; break; case Usage.Wheel: this.Name = "Wheel"; this.Type = AxisType.Wheel; break; case Usage.Slider: this.Name = "Slider"; this.Type = AxisType.Slider; break; } break; case UsagePage.Simulation: switch (this.usage) { case Usage.Rudder: this.Name = "Rudder"; this.Type = AxisType.Rudder; break; case Usage.Throttle: this.Name = "Throttle"; this.Type = AxisType.Throttle; break; } break; } }
public HidDevice(string path) { //device mutex lockObject = new object(); //static buffers strBuffer = new StringBuilder(256); //open device //TODO why is 0x40000000 missing from FileAttribute in PInvoke? reference = Kernel32.CreateFile(path, Kernel32.ACCESS_MASK.GenericRight.GENERIC_WRITE, Kernel32.FileShare.FILE_SHARE_READ | Kernel32.FileShare.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.CreationDisposition.OPEN_EXISTING, Kernel32.CreateFileFlags.FILE_FLAG_OVERLAPPED, Kernel32.SafeObjectHandle.Null); if (reference.IsInvalid) { return; } //overlapped fileEvent = new ManualResetEvent(false); fileOverlapped = new SafeOverlapped(fileEvent); //get preparsed data if (!Hid.HidD_GetPreparsedData(reference, out preparsedData)) { return; } //transfer buffers capabilities = Hid.HidP_GetCaps(preparsedData); inBuffer = new byte[capabilities.InputReportByteLength]; outBuffer = new byte[capabilities.OutputReportByteLength]; featureBuffer = new byte[capabilities.FeatureReportByteLength]; //dynamic caps inputValueCaps = new List <ValueCaps>(); outputValueCaps = new List <ValueCaps>(); featureValueCaps = new List <ValueCaps>(); ushort numInputCaps = capabilities.NumberInputValueCaps; ushort numOutputCaps = capabilities.NumberOutputValueCaps; ushort numFeatureCaps = capabilities.NumberFeatureValueCaps; ushort maxValueCaps = Math.Max(numInputCaps, numOutputCaps); maxValueCaps = Math.Max(maxValueCaps, numFeatureCaps); int valueCapSize = Marshal.SizeOf <ValueCaps>(); IntPtr valueCapPtr = Marshal.AllocHGlobal(maxValueCaps * valueCapSize); HidPStatus stat = Hid.HidP_GetValueCaps(ReportType.Input, valueCapPtr, ref numInputCaps, preparsedData); for (int i = 0; i < numInputCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + (i * valueCapSize))); inputValueCaps.Add(val); } stat = Hid.HidP_GetValueCaps(ReportType.Output, valueCapPtr, ref numOutputCaps, preparsedData); for (int i = 0; i < numOutputCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + i * valueCapSize)); outputValueCaps.Add(val); } stat = Hid.HidP_GetValueCaps(ReportType.Feature, valueCapPtr, ref numFeatureCaps, preparsedData); for (int i = 0; i < numFeatureCaps; i++) { ValueCaps val = Marshal.PtrToStructure <ValueCaps>(new IntPtr(valueCapPtr.ToInt64() + i * valueCapSize)); featureValueCaps.Add(val); } Marshal.FreeHGlobal(valueCapPtr); }