summaryrefslogtreecommitdiff
path: root/grapher/Models
diff options
context:
space:
mode:
Diffstat (limited to 'grapher/Models')
-rw-r--r--grapher/Models/AccelGUI.cs15
-rw-r--r--grapher/Models/Calculations/AccelCalculator.cs10
-rw-r--r--grapher/Models/Calculations/AccelChartData.cs12
-rw-r--r--grapher/Models/Calculations/AccelData.cs32
-rw-r--r--grapher/Models/Charts/AccelCharts.cs73
-rw-r--r--grapher/Models/Charts/ChartXY.cs90
-rw-r--r--grapher/Models/Mouse/MouseWatcher.cs723
7 files changed, 912 insertions, 43 deletions
diff --git a/grapher/Models/AccelGUI.cs b/grapher/Models/AccelGUI.cs
index 5a46a73..a63bf07 100644
--- a/grapher/Models/AccelGUI.cs
+++ b/grapher/Models/AccelGUI.cs
@@ -1,4 +1,5 @@
using grapher.Models.Calculations;
+using grapher.Models.Mouse;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
@@ -11,7 +12,7 @@ using System.Windows.Forms.DataVisualization.Charting;
namespace grapher
{
public class AccelGUI
- {
+ {
#region constructors
@@ -28,7 +29,8 @@ namespace grapher
Option acceleration,
Option limtOrExp,
Option midpoint,
- Button writeButton)
+ Button writeButton,
+ Label mouseMoveLabel)
{
AccelForm = accelForm;
AccelCharts = accelCharts;
@@ -43,10 +45,11 @@ namespace grapher
LimitOrExponent = limtOrExp;
Midpoint = midpoint;
WriteButton = writeButton;
- AccelData = new AccelData();
ManagedAcceleration.ReadFromDriver();
UpdateGraph();
+
+ MouseWatcher = new MouseWatcher(AccelForm, mouseMoveLabel, AccelCharts);
}
#endregion constructors
@@ -79,7 +82,7 @@ namespace grapher
public Button WriteButton { get; }
- public AccelData AccelData { get; }
+ public MouseWatcher MouseWatcher { get; }
#endregion properties
@@ -88,8 +91,8 @@ namespace grapher
public void UpdateGraph()
{
- AccelCalculator.Calculate(AccelData, ManagedAcceleration, Sensitivity.Fields.X);
- AccelCharts.Bind(AccelData);
+ AccelCalculator.Calculate(AccelCharts.AccelData, ManagedAcceleration, Sensitivity.Fields.X, Sensitivity.Fields.Y);
+ AccelCharts.Bind();
}
#endregion methods
diff --git a/grapher/Models/Calculations/AccelCalculator.cs b/grapher/Models/Calculations/AccelCalculator.cs
index a768ee9..d61a59b 100644
--- a/grapher/Models/Calculations/AccelCalculator.cs
+++ b/grapher/Models/Calculations/AccelCalculator.cs
@@ -23,13 +23,13 @@ namespace grapher.Models.Calculations
public static ReadOnlyCollection<MagnitudeData> MagnitudesX = GetMagnitudesX();
public static ReadOnlyCollection<MagnitudeData> MagnitudesY = GetMagnitudesY();
- public static void Calculate(AccelData data, ManagedAccel accel, double starter)
+ public static void Calculate(AccelData data, ManagedAccel accel, double starterX, double starterY)
{
data.Clear();
- Calculate(data.Combined, accel, starter, MagnitudesCombined);
- Calculate(data.X, accel, starter, MagnitudesX);
- Calculate(data.Y, accel, starter, MagnitudesY);
+ Calculate(data.Combined, accel, starterX, MagnitudesCombined);
+ Calculate(data.X, accel, starterY, MagnitudesX);
+ Calculate(data.Y, accel, starterY, MagnitudesY);
}
public static void Calculate(AccelChartData data, ManagedAccel accel, double starter, ICollection<MagnitudeData> magnitudeData)
@@ -37,7 +37,7 @@ namespace grapher.Models.Calculations
double lastInputMagnitude = 0;
double lastOutputMagnitude = 0;
- foreach (var magnitudeDatum in MagnitudesCombined)
+ foreach (var magnitudeDatum in magnitudeData)
{
var output = accel.Accelerate(magnitudeDatum.x, magnitudeDatum.y, 1);
diff --git a/grapher/Models/Calculations/AccelChartData.cs b/grapher/Models/Calculations/AccelChartData.cs
index 243827a..a3354aa 100644
--- a/grapher/Models/Calculations/AccelChartData.cs
+++ b/grapher/Models/Calculations/AccelChartData.cs
@@ -27,5 +27,17 @@ namespace grapher.Models.Calculations
VelocityPoints.Clear();
GainPoints.Clear();
}
+
+ public (double, double, double) FindInValuesFromOut(double outVelocityValue)
+ {
+ var velIdx = ~VelocityPoints.Values.ToList().BinarySearch(outVelocityValue);
+
+ if (velIdx < 0)
+ {
+ velIdx = ~velIdx;
+ }
+
+ return (VelocityPoints.ElementAt(velIdx).Key, AccelPoints.ElementAt(velIdx).Value, GainPoints.ElementAt(velIdx).Value);
+ }
}
}
diff --git a/grapher/Models/Calculations/AccelData.cs b/grapher/Models/Calculations/AccelData.cs
index a2a6a3a..a8f3307 100644
--- a/grapher/Models/Calculations/AccelData.cs
+++ b/grapher/Models/Calculations/AccelData.cs
@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using static grapher.AccelCharts;
namespace grapher.Models.Calculations
{
public class AccelData
{
+
public AccelData()
{
Combined = new AccelChartData();
@@ -27,5 +29,35 @@ namespace grapher.Models.Calculations
X.Clear();
Y.Clear();
}
+
+ public void CalculateDots(int x, int y, ref EstimatedPoints estimation)
+ {
+ var magnitude = AccelCalculator.Magnitude(x, y);
+
+ estimation.CombinedVelocity.Y = magnitude;
+ estimation.XVelocity.Y = Math.Abs(x);
+ estimation.YVelocity.Y = Math.Abs(y);
+
+ (var inCombVel, var combSens, var combGain) = Combined.FindInValuesFromOut(magnitude);
+ estimation.CombinedVelocity.X = inCombVel;
+ estimation.CombinedSensitivity.X = inCombVel;
+ estimation.CombinedGain.X = inCombVel;
+ estimation.CombinedSensitivity.Y = combSens;
+ estimation.CombinedGain.Y = combGain;
+
+ (var inXVel, var xSens, var xGain) = X.FindInValuesFromOut(estimation.XVelocity.Y);
+ estimation.XVelocity.X = inXVel;
+ estimation.XSensitivity.X = inXVel;
+ estimation.XGain.X = inXVel;
+ estimation.XSensitivity.Y = xSens;
+ estimation.XGain.Y = xGain;
+
+ (var inYVel, var ySens, var yGain) = Y.FindInValuesFromOut(estimation.YVelocity.Y);
+ estimation.YVelocity.X = inYVel;
+ estimation.YSensitivity.X = inYVel;
+ estimation.YGain.X = inYVel;
+ estimation.YSensitivity.Y = ySens;
+ estimation.YGain.Y = yGain;
+ }
}
}
diff --git a/grapher/Models/Charts/AccelCharts.cs b/grapher/Models/Charts/AccelCharts.cs
index 0728abc..e593bb9 100644
--- a/grapher/Models/Charts/AccelCharts.cs
+++ b/grapher/Models/Charts/AccelCharts.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
+using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
@@ -12,6 +13,27 @@ namespace grapher
{
public class AccelCharts
{
+ public struct ChartPoint
+ {
+ public double X;
+ public double Y;
+ }
+
+ public struct EstimatedPoints
+ {
+ public ChartPoint CombinedVelocity;
+ public ChartPoint CombinedSensitivity;
+ public ChartPoint CombinedGain;
+
+ public ChartPoint XVelocity;
+ public ChartPoint XSensitivity;
+ public ChartPoint XGain;
+
+ public ChartPoint YVelocity;
+ public ChartPoint YSensitivity;
+ public ChartPoint YGain;
+ }
+
public const int ChartSeparationVertical = 10;
/// <summary> Needed to show full contents in form. Unsure why. </summary>
@@ -31,6 +53,22 @@ namespace grapher
GainChart = gainChart;
EnableVelocityAndGain = enableVelocityAndGain;
CheckBoxesXY = checkBoxesXY;
+ AccelData = new AccelData();
+
+ Estimated = new EstimatedPoints
+ {
+ CombinedVelocity = new ChartPoint { X = 0, Y = 0 },
+ CombinedSensitivity = new ChartPoint { X = 0, Y = 0 },
+ CombinedGain = new ChartPoint { X = 0, Y = 0 },
+
+ XVelocity = new ChartPoint { X = 0, Y = 0 },
+ XSensitivity = new ChartPoint { X = 0, Y = 0 },
+ XGain = new ChartPoint { X = 0, Y = 0 },
+
+ YVelocity = new ChartPoint { X = 0, Y = 0 },
+ YSensitivity = new ChartPoint { X = 0, Y = 0 },
+ YGain = new ChartPoint { X = 0, Y = 0 },
+ };
SensitivityChart.SetTop(0);
VelocityChart.SetHeight(SensitivityChart.Height);
@@ -45,6 +83,7 @@ namespace grapher
EnableVelocityAndGain.CheckedChanged += new System.EventHandler(OnEnableCheckStateChange);
HideVelocityAndGain();
+ Combined = false;
ShowCombined();
}
@@ -58,25 +97,37 @@ namespace grapher
public ToolStripMenuItem EnableVelocityAndGain { get; }
+ public AccelData AccelData { get; }
+
+ private EstimatedPoints Estimated;
+
private ICollection<CheckBox> CheckBoxesXY { get; }
private bool Combined { get; set; }
private int FormBorderHeight { get; }
- public void Bind(AccelData data)
+ public void MakeDots(int x, int y)
+ {
+ AccelData.CalculateDots(x, y, ref Estimated);
+ SensitivityChart.DrawPoints(Estimated.CombinedSensitivity, Estimated.XSensitivity, Estimated.YSensitivity);
+ VelocityChart.DrawPoints(Estimated.CombinedVelocity, Estimated.XVelocity, Estimated.YVelocity);
+ GainChart.DrawPoints(Estimated.CombinedGain, Estimated.XGain, Estimated.YGain);
+ }
+
+ public void Bind()
{
if (Combined)
{
- SensitivityChart.Bind(data.Combined.AccelPoints);
- VelocityChart.Bind(data.Combined.VelocityPoints);
- GainChart.Bind(data.Combined.GainPoints);
+ SensitivityChart.Bind(AccelData.Combined.AccelPoints);
+ VelocityChart.Bind(AccelData.Combined.VelocityPoints);
+ GainChart.Bind(AccelData.Combined.GainPoints);
}
else
{
- SensitivityChart.BindXY(data.X.AccelPoints, data.Y.AccelPoints);
- VelocityChart.BindXY(data.X.VelocityPoints, data.Y.VelocityPoints);
- GainChart.BindXY(data.X.GainPoints, data.Y.GainPoints);
+ SensitivityChart.BindXY(AccelData.X.AccelPoints, AccelData.Y.AccelPoints);
+ VelocityChart.BindXY(AccelData.X.VelocityPoints, AccelData.Y.VelocityPoints);
+ GainChart.BindXY(AccelData.X.GainPoints, AccelData.Y.GainPoints);
}
}
@@ -132,11 +183,13 @@ namespace grapher
{
if (Combined)
{
+ Combined = false;
+
SensitivityChart.SetSeparate();
VelocityChart.SetSeparate();
GainChart.SetSeparate();
UpdateFormWidth();
- Combined = false;
+ Bind();
}
}
@@ -144,11 +197,13 @@ namespace grapher
{
if (!Combined)
{
+ Combined = true;
+
SensitivityChart.SetCombined();
VelocityChart.SetCombined();
GainChart.SetCombined();
UpdateFormWidth();
- Combined = true;
+ Bind();
}
}
diff --git a/grapher/Models/Charts/ChartXY.cs b/grapher/Models/Charts/ChartXY.cs
index 7bb7ac8..2c0ce2c 100644
--- a/grapher/Models/Charts/ChartXY.cs
+++ b/grapher/Models/Charts/ChartXY.cs
@@ -1,18 +1,26 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
+using static grapher.AccelCharts;
namespace grapher
{
public class ChartXY
{
+ #region Consts
+
public const int ChartSeparationHorizontal = 10;
+ #endregion Consts
+
+ #region Constructors
+
public ChartXY(Chart chartX, Chart chartY)
{
ChartX = chartX;
@@ -27,31 +35,13 @@ namespace grapher
SetupChart(ChartY);
}
- public Chart ChartX { get; }
-
- public Chart ChartY { get; }
-
- public static void SetupChart(Chart chart)
- {
- chart.ChartAreas[0].AxisX.RoundAxisValues();
-
- chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
- chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-
- chart.ChartAreas[0].AxisY.ScaleView.MinSize = 0.01;
- chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = 0.001;
-
- chart.ChartAreas[0].CursorY.Interval = 0.001;
+ #endregion Constructors
- chart.ChartAreas[0].CursorX.AutoScroll = true;
- chart.ChartAreas[0].CursorY.AutoScroll = true;
+ #region Properties
- chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
- chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+ public Chart ChartX { get; }
- chart.ChartAreas[0].CursorX.IsUserEnabled = true;
- chart.ChartAreas[0].CursorY.IsUserEnabled = true;
- }
+ public Chart ChartY { get; }
public int Height {
get
@@ -77,7 +67,7 @@ namespace grapher
public int Top {
get
{
- return ChartX.Height;
+ return ChartX.Top;
}
}
@@ -90,6 +80,58 @@ namespace grapher
public bool Combined { get; private set; }
+ #endregion Properties
+
+ #region Methods
+
+ public static void SetupChart(Chart chart)
+ {
+ chart.ChartAreas[0].AxisX.RoundAxisValues();
+
+ chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+ chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+
+ chart.ChartAreas[0].AxisY.ScaleView.MinSize = 0.01;
+ chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = 0.001;
+
+ chart.ChartAreas[0].CursorY.Interval = 0.001;
+
+ chart.ChartAreas[0].CursorX.AutoScroll = true;
+ chart.ChartAreas[0].CursorY.AutoScroll = true;
+
+ chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+ chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+
+ chart.ChartAreas[0].CursorX.IsUserEnabled = true;
+ chart.ChartAreas[0].CursorY.IsUserEnabled = true;
+
+ chart.Series[1].Points.Clear();
+ chart.Series[1].Points.AddXY(0, 0);
+ }
+
+ public static void DrawPoint(Chart chart, ChartPoint point)
+ {
+ chart.Series[1].Points[0].XValue = point.X;
+ chart.Series[1].Points[0].YValues[0] = point.Y;
+ }
+
+ public void DrawPoints(ChartPoint CombinedPoint, ChartPoint XPoint, ChartPoint YPoint)
+ {
+ if (Combined)
+ {
+ DrawPoint(ChartX, CombinedPoint);
+ }
+ else
+ {
+ DrawPoint(ChartX, XPoint);
+ }
+
+ if (ChartY.Visible)
+ {
+ DrawPoint(ChartY, YPoint);
+ }
+ }
+
public void Bind(IDictionary data)
{
ChartX.Series[0].Points.DataBindXY(data.Keys, data.Values);
@@ -150,5 +192,7 @@ namespace grapher
ChartX.Height = height;
ChartY.Height = height;
}
+
+ #endregion Methods
}
}
diff --git a/grapher/Models/Mouse/MouseWatcher.cs b/grapher/Models/Mouse/MouseWatcher.cs
new file mode 100644
index 0000000..9b1479e
--- /dev/null
+++ b/grapher/Models/Mouse/MouseWatcher.cs
@@ -0,0 +1,723 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace grapher.Models.Mouse
+{
+ public class MouseWatcher
+ {
+ /// <summary>
+ /// Enumeration containing HID usage page flags.
+ /// </summary>
+ public enum HIDUsagePage : ushort
+ {
+ /// <summary>Unknown usage page.</summary>
+ Undefined = 0x00,
+ /// <summary>Generic desktop controls.</summary>
+ Generic = 0x01,
+ /// <summary>Simulation controls.</summary>
+ Simulation = 0x02,
+ /// <summary>Virtual reality controls.</summary>
+ VR = 0x03,
+ /// <summary>Sports controls.</summary>
+ Sport = 0x04,
+ /// <summary>Games controls.</summary>
+ Game = 0x05,
+ /// <summary>Keyboard controls.</summary>
+ Keyboard = 0x07,
+ /// <summary>LED controls.</summary>
+ LED = 0x08,
+ /// <summary>Button.</summary>
+ Button = 0x09,
+ /// <summary>Ordinal.</summary>
+ Ordinal = 0x0A,
+ /// <summary>Telephony.</summary>
+ Telephony = 0x0B,
+ /// <summary>Consumer.</summary>
+ Consumer = 0x0C,
+ /// <summary>Digitizer.</summary>
+ Digitizer = 0x0D,
+ /// <summary>Physical interface device.</summary>
+ PID = 0x0F,
+ /// <summary>Unicode.</summary>
+ Unicode = 0x10,
+ /// <summary>Alphanumeric display.</summary>
+ AlphaNumeric = 0x14,
+ /// <summary>Medical instruments.</summary>
+ Medical = 0x40,
+ /// <summary>Monitor page 0.</summary>
+ MonitorPage0 = 0x80,
+ /// <summary>Monitor page 1.</summary>
+ MonitorPage1 = 0x81,
+ /// <summary>Monitor page 2.</summary>
+ MonitorPage2 = 0x82,
+ /// <summary>Monitor page 3.</summary>
+ MonitorPage3 = 0x83,
+ /// <summary>Power page 0.</summary>
+ PowerPage0 = 0x84,
+ /// <summary>Power page 1.</summary>
+ PowerPage1 = 0x85,
+ /// <summary>Power page 2.</summary>
+ PowerPage2 = 0x86,
+ /// <summary>Power page 3.</summary>
+ PowerPage3 = 0x87,
+ /// <summary>Bar code scanner.</summary>
+ BarCode = 0x8C,
+ /// <summary>Scale page.</summary>
+ Scale = 0x8D,
+ /// <summary>Magnetic strip reading devices.</summary>
+ MSR = 0x8E
+ }
+
+ /// <summary>
+ /// Enumeration containing the HID usage values.
+ /// </summary>
+ public enum HIDUsage : ushort
+ {
+ /// <summary></summary>
+ Pointer = 0x01,
+ /// <summary></summary>
+ Mouse = 0x02,
+ /// <summary></summary>
+ Joystick = 0x04,
+ /// <summary></summary>
+ Gamepad = 0x05,
+ /// <summary></summary>
+ Keyboard = 0x06,
+ /// <summary></summary>
+ Keypad = 0x07,
+ /// <summary></summary>
+ SystemControl = 0x80,
+ /// <summary></summary>
+ X = 0x30,
+ /// <summary></summary>
+ Y = 0x31,
+ /// <summary></summary>
+ Z = 0x32,
+ /// <summary></summary>
+ RelativeX = 0x33,
+ /// <summary></summary>
+ RelativeY = 0x34,
+ /// <summary></summary>
+ RelativeZ = 0x35,
+ /// <summary></summary>
+ Slider = 0x36,
+ /// <summary></summary>
+ Dial = 0x37,
+ /// <summary></summary>
+ Wheel = 0x38,
+ /// <summary></summary>
+ HatSwitch = 0x39,
+ /// <summary></summary>
+ CountedBuffer = 0x3A,
+ /// <summary></summary>
+ ByteCount = 0x3B,
+ /// <summary></summary>
+ MotionWakeup = 0x3C,
+ /// <summary></summary>
+ VX = 0x40,
+ /// <summary></summary>
+ VY = 0x41,
+ /// <summary></summary>
+ VZ = 0x42,
+ /// <summary></summary>
+ VBRX = 0x43,
+ /// <summary></summary>
+ VBRY = 0x44,
+ /// <summary></summary>
+ VBRZ = 0x45,
+ /// <summary></summary>
+ VNO = 0x46,
+ /// <summary></summary>
+ SystemControlPower = 0x81,
+ /// <summary></summary>
+ SystemControlSleep = 0x82,
+ /// <summary></summary>
+ SystemControlWake = 0x83,
+ /// <summary></summary>
+ SystemControlContextMenu = 0x84,
+ /// <summary></summary>
+ SystemControlMainMenu = 0x85,
+ /// <summary></summary>
+ SystemControlApplicationMenu = 0x86,
+ /// <summary></summary>
+ SystemControlHelpMenu = 0x87,
+ /// <summary></summary>
+ SystemControlMenuExit = 0x88,
+ /// <summary></summary>
+ SystemControlMenuSelect = 0x89,
+ /// <summary></summary>
+ SystemControlMenuRight = 0x8A,
+ /// <summary></summary>
+ SystemControlMenuLeft = 0x8B,
+ /// <summary></summary>
+ SystemControlMenuUp = 0x8C,
+ /// <summary></summary>
+ SystemControlMenuDown = 0x8D,
+ /// <summary></summary>
+ KeyboardNoEvent = 0x00,
+ /// <summary></summary>
+ KeyboardRollover = 0x01,
+ /// <summary></summary>
+ KeyboardPostFail = 0x02,
+ /// <summary></summary>
+ KeyboardUndefined = 0x03,
+ /// <summary></summary>
+ KeyboardaA = 0x04,
+ /// <summary></summary>
+ KeyboardzZ = 0x1D,
+ /// <summary></summary>
+ Keyboard1 = 0x1E,
+ /// <summary></summary>
+ Keyboard0 = 0x27,
+ /// <summary></summary>
+ KeyboardLeftControl = 0xE0,
+ /// <summary></summary>
+ KeyboardLeftShift = 0xE1,
+ /// <summary></summary>
+ KeyboardLeftALT = 0xE2,
+ /// <summary></summary>
+ KeyboardLeftGUI = 0xE3,
+ /// <summary></summary>
+ KeyboardRightControl = 0xE4,
+ /// <summary></summary>
+ KeyboardRightShift = 0xE5,
+ /// <summary></summary>
+ KeyboardRightALT = 0xE6,
+ /// <summary></summary>
+ KeyboardRightGUI = 0xE7,
+ /// <summary></summary>
+ KeyboardScrollLock = 0x47,
+ /// <summary></summary>
+ KeyboardNumLock = 0x53,
+ /// <summary></summary>
+ KeyboardCapsLock = 0x39,
+ /// <summary></summary>
+ KeyboardF1 = 0x3A,
+ /// <summary></summary>
+ KeyboardF12 = 0x45,
+ /// <summary></summary>
+ KeyboardReturn = 0x28,
+ /// <summary></summary>
+ KeyboardEscape = 0x29,
+ /// <summary></summary>
+ KeyboardDelete = 0x2A,
+ /// <summary></summary>
+ KeyboardPrintScreen = 0x46,
+ /// <summary></summary>
+ LEDNumLock = 0x01,
+ /// <summary></summary>
+ LEDCapsLock = 0x02,
+ /// <summary></summary>
+ LEDScrollLock = 0x03,
+ /// <summary></summary>
+ LEDCompose = 0x04,
+ /// <summary></summary>
+ LEDKana = 0x05,
+ /// <summary></summary>
+ LEDPower = 0x06,
+ /// <summary></summary>
+ LEDShift = 0x07,
+ /// <summary></summary>
+ LEDDoNotDisturb = 0x08,
+ /// <summary></summary>
+ LEDMute = 0x09,
+ /// <summary></summary>
+ LEDToneEnable = 0x0A,
+ /// <summary></summary>
+ LEDHighCutFilter = 0x0B,
+ /// <summary></summary>
+ LEDLowCutFilter = 0x0C,
+ /// <summary></summary>
+ LEDEqualizerEnable = 0x0D,
+ /// <summary></summary>
+ LEDSoundFieldOn = 0x0E,
+ /// <summary></summary>
+ LEDSurroundFieldOn = 0x0F,
+ /// <summary></summary>
+ LEDRepeat = 0x10,
+ /// <summary></summary>
+ LEDStereo = 0x11,
+ /// <summary></summary>
+ LEDSamplingRateDirect = 0x12,
+ /// <summary></summary>
+ LEDSpinning = 0x13,
+ /// <summary></summary>
+ LEDCAV = 0x14,
+ /// <summary></summary>
+ LEDCLV = 0x15,
+ /// <summary></summary>
+ LEDRecordingFormatDet = 0x16,
+ /// <summary></summary>
+ LEDOffHook = 0x17,
+ /// <summary></summary>
+ LEDRing = 0x18,
+ /// <summary></summary>
+ LEDMessageWaiting = 0x19,
+ /// <summary></summary>
+ LEDDataMode = 0x1A,
+ /// <summary></summary>
+ LEDBatteryOperation = 0x1B,
+ /// <summary></summary>
+ LEDBatteryOK = 0x1C,
+ /// <summary></summary>
+ LEDBatteryLow = 0x1D,
+ /// <summary></summary>
+ LEDSpeaker = 0x1E,
+ /// <summary></summary>
+ LEDHeadset = 0x1F,
+ /// <summary></summary>
+ LEDHold = 0x20,
+ /// <summary></summary>
+ LEDMicrophone = 0x21,
+ /// <summary></summary>
+ LEDCoverage = 0x22,
+ /// <summary></summary>
+ LEDNightMode = 0x23,
+ /// <summary></summary>
+ LEDSendCalls = 0x24,
+ /// <summary></summary>
+ LEDCallPickup = 0x25,
+ /// <summary></summary>
+ LEDConference = 0x26,
+ /// <summary></summary>
+ LEDStandBy = 0x27,
+ /// <summary></summary>
+ LEDCameraOn = 0x28,
+ /// <summary></summary>
+ LEDCameraOff = 0x29,
+ /// <summary></summary>
+ LEDOnLine = 0x2A,
+ /// <summary></summary>
+ LEDOffLine = 0x2B,
+ /// <summary></summary>
+ LEDBusy = 0x2C,
+ /// <summary></summary>
+ LEDReady = 0x2D,
+ /// <summary></summary>
+ LEDPaperOut = 0x2E,
+ /// <summary></summary>
+ LEDPaperJam = 0x2F,
+ /// <summary></summary>
+ LEDRemote = 0x30,
+ /// <summary></summary>
+ LEDForward = 0x31,
+ /// <summary></summary>
+ LEDReverse = 0x32,
+ /// <summary></summary>
+ LEDStop = 0x33,
+ /// <summary></summary>
+ LEDRewind = 0x34,
+ /// <summary></summary>
+ LEDFastForward = 0x35,
+ /// <summary></summary>
+ LEDPlay = 0x36,
+ /// <summary></summary>
+ LEDPause = 0x37,
+ /// <summary></summary>
+ LEDRecord = 0x38,
+ /// <summary></summary>
+ LEDError = 0x39,
+ /// <summary></summary>
+ LEDSelectedIndicator = 0x3A,
+ /// <summary></summary>
+ LEDInUseIndicator = 0x3B,
+ /// <summary></summary>
+ LEDMultiModeIndicator = 0x3C,
+ /// <summary></summary>
+ LEDIndicatorOn = 0x3D,
+ /// <summary></summary>
+ LEDIndicatorFlash = 0x3E,
+ /// <summary></summary>
+ LEDIndicatorSlowBlink = 0x3F,
+ /// <summary></summary>
+ LEDIndicatorFastBlink = 0x40,
+ /// <summary></summary>
+ LEDIndicatorOff = 0x41,
+ /// <summary></summary>
+ LEDFlashOnTime = 0x42,
+ /// <summary></summary>
+ LEDSlowBlinkOnTime = 0x43,
+ /// <summary></summary>
+ LEDSlowBlinkOffTime = 0x44,
+ /// <summary></summary>
+ LEDFastBlinkOnTime = 0x45,
+ /// <summary></summary>
+ LEDFastBlinkOffTime = 0x46,
+ /// <summary></summary>
+ LEDIndicatorColor = 0x47,
+ /// <summary></summary>
+ LEDRed = 0x48,
+ /// <summary></summary>
+ LEDGreen = 0x49,
+ /// <summary></summary>
+ LEDAmber = 0x4A,
+ /// <summary></summary>
+ LEDGenericIndicator = 0x3B,
+ /// <summary></summary>
+ TelephonyPhone = 0x01,
+ /// <summary></summary>
+ TelephonyAnsweringMachine = 0x02,
+ /// <summary></summary>
+ TelephonyMessageControls = 0x03,
+ /// <summary></summary>
+ TelephonyHandset = 0x04,
+ /// <summary></summary>
+ TelephonyHeadset = 0x05,
+ /// <summary></summary>
+ TelephonyKeypad = 0x06,
+ /// <summary></summary>
+ TelephonyProgrammableButton = 0x07,
+ /// <summary></summary>
+ SimulationRudder = 0xBA,
+ /// <summary></summary>
+ SimulationThrottle = 0xBB
+ }
+
+ /// <summary>Enumeration containing flags for a raw input device.</summary>
+ [Flags()]
+ public enum RawInputDeviceFlags
+ {
+ /// <summary>No flags.</summary>
+ None = 0,
+ /// <summary>If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.</summary>
+ Remove = 0x00000001,
+ /// <summary>If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with PageOnly.</summary>
+ Exclude = 0x00000010,
+ /// <summary>If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that Usage must be zero. To exclude a particular top level collection, use Exclude.</summary>
+ PageOnly = 0x00000020,
+ /// <summary>If set, this prevents any devices specified by UsagePage or Usage from generating legacy messages. This is only for the mouse and keyboard.</summary>
+ NoLegacy = 0x00000030,
+ /// <summary>If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that WindowHandle must be specified.</summary>
+ InputSink = 0x00000100,
+ /// <summary>If set, the mouse button click does not activate the other window.</summary>
+ CaptureMouse = 0x00000200,
+ /// <summary>If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. NoHotKeys can be specified even if NoLegacy is not specified and WindowHandle is NULL.</summary>
+ NoHotKeys = 0x00000200,
+ /// <summary>If set, application keys are handled. NoLegacy must be specified. Keyboard only.</summary>
+ AppKeys = 0x00000400
+ }
+
+ /// <summary>Value type for raw input devices.</summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RAWINPUTDEVICE
+ {
+ /// <summary>Top level collection Usage page for the raw input device.</summary>
+ public HIDUsagePage UsagePage;
+ /// <summary>Top level collection Usage for the raw input device. </summary>
+ public HIDUsage Usage;
+ /// <summary>Mode flag that specifies how to interpret the information provided by UsagePage and Usage.</summary>
+ public RawInputDeviceFlags Flags;
+ /// <summary>Handle to the target device. If NULL, it follows the keyboard focus.</summary>
+ public IntPtr WindowHandle;
+ }
+
+ /// <summary>
+ /// Contains the raw input from a device.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RawInput
+ {
+ /// <summary>
+ /// Header for the data.
+ /// </summary>
+ public RAWINPUTHEADER Header;
+ public Union Data;
+ [StructLayout(LayoutKind.Explicit)]
+ public struct Union
+ {
+ /// <summary>
+ /// Mouse raw input data.
+ /// </summary>
+ [FieldOffset(0)]
+ public RawMouse Mouse;
+ /// <summary>
+ /// Keyboard raw input data.
+ /// </summary>
+ [FieldOffset(0)]
+ public RawKeyboard Keyboard;
+ /// <summary>
+ /// HID raw input data.
+ /// </summary>
+ [FieldOffset(0)]
+ public RawHID HID;
+ }
+ }
+
+ /// <summary>
+ /// Value type for raw input from a HID.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RawHID
+ {
+ /// <summary>Size of the HID data in bytes.</summary>
+ public int Size;
+ /// <summary>Number of HID in Data.</summary>
+ public int Count;
+ /// <summary>Data for the HID.</summary>
+ public IntPtr Data;
+ }
+
+ /// <summary>
+ /// Value type for a raw input header.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RAWINPUTHEADER
+ {
+ /// <summary>Type of device the input is coming from.</summary>
+ public RawInputType Type;
+ /// <summary>Size of the packet of data.</summary>
+ public int Size;
+ /// <summary>Handle to the device sending the data.</summary>
+ public IntPtr Device;
+ /// <summary>wParam from the window message.</summary>
+ public IntPtr wParam;
+ }
+
+ /// <summary>
+ /// Enumeration containing the type device the raw input is coming from.
+ /// </summary>
+ public enum RawInputType
+ {
+ /// <summary>
+ /// Mouse input.
+ /// </summary>
+ Mouse = 0,
+
+ /// <summary>
+ /// Keyboard input.
+ /// </summary>
+ Keyboard = 1,
+
+ /// <summary>
+ /// Human interface device input.
+ /// </summary>
+ HID = 2,
+
+ /// <summary>
+ /// Another device that is not the keyboard or the mouse.
+ /// </summary>
+ Other = 3
+ }
+
+ /// <summary>
+ /// Contains information about the state of the mouse.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RawMouse
+ {
+ /// <summary>
+ /// The mouse state.
+ /// </summary>
+ public RawMouseFlags Flags;
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct Data
+ {
+ [FieldOffset(0)]
+ public uint Buttons;
+ /// <summary>
+ /// If the mouse wheel is moved, this will contain the delta amount.
+ /// </summary>
+ [FieldOffset(2)]
+ public ushort ButtonData;
+ /// <summary>
+ /// Flags for the event.
+ /// </summary>
+ [FieldOffset(0)]
+ public RawMouseButtons ButtonFlags;
+ }
+
+ public Data _Data;
+
+ /// <summary>
+ /// Raw button data.
+ /// </summary>
+ public uint RawButtons;
+ /// <summary>
+ /// The motion in the X direction. This is signed relative motion or
+ /// absolute motion, depending on the value of usFlags.
+ /// </summary>
+ public int LastX;
+ /// <summary>
+ /// The motion in the Y direction. This is signed relative motion or absolute motion,
+ /// depending on the value of usFlags.
+ /// </summary>
+ public int LastY;
+ /// <summary>
+ /// The device-specific additional information for the event.
+ /// </summary>
+ public uint ExtraInformation;
+ }
+
+ /// <summary>
+ /// Enumeration containing the flags for raw mouse data.
+ /// </summary>
+ [Flags()]
+ public enum RawMouseFlags
+ : ushort
+ {
+ /// <summary>Relative to the last position.</summary>
+ MoveRelative = 0,
+ /// <summary>Absolute positioning.</summary>
+ MoveAbsolute = 1,
+ /// <summary>Coordinate data is mapped to a virtual desktop.</summary>
+ VirtualDesktop = 2,
+ /// <summary>Attributes for the mouse have changed.</summary>
+ AttributesChanged = 4
+ }
+
+ /// <summary>
+ /// Enumeration containing the button data for raw mouse input.
+ /// </summary>
+ [Flags()]
+ public enum RawMouseButtons
+ : ushort
+ {
+ /// <summary>No button.</summary>
+ None = 0,
+ /// <summary>Left (button 1) down.</summary>
+ LeftDown = 0x0001,
+ /// <summary>Left (button 1) up.</summary>
+ LeftUp = 0x0002,
+ /// <summary>Right (button 2) down.</summary>
+ RightDown = 0x0004,
+ /// <summary>Right (button 2) up.</summary>
+ RightUp = 0x0008,
+ /// <summary>Middle (button 3) down.</summary>
+ MiddleDown = 0x0010,
+ /// <summary>Middle (button 3) up.</summary>
+ MiddleUp = 0x0020,
+ /// <summary>Button 4 down.</summary>
+ Button4Down = 0x0040,
+ /// <summary>Button 4 up.</summary>
+ Button4Up = 0x0080,
+ /// <summary>Button 5 down.</summary>
+ Button5Down = 0x0100,
+ /// <summary>Button 5 up.</summary>
+ Button5Up = 0x0200,
+ /// <summary>Mouse wheel moved.</summary>
+ MouseWheel = 0x0400
+ }
+
+ /// <summary>
+ /// Value type for raw input from a keyboard.
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential)]
+ public struct RawKeyboard
+ {
+ /// <summary>Scan code for key depression.</summary>
+ public short MakeCode;
+ /// <summary>Scan code information.</summary>
+ public RawKeyboardFlags Flags;
+ /// <summary>Reserved.</summary>
+ public short Reserved;
+ /// <summary>Virtual key code.</summary>
+ public ushort VirtualKey;
+ /// <summary>Corresponding window message.</summary>
+ public uint Message;
+ /// <summary>Extra information.</summary>
+ public int ExtraInformation;
+ }
+
+ /// <summary>
+ /// Enumeration containing flags for raw keyboard input.
+ /// </summary>
+ [Flags]
+ public enum RawKeyboardFlags : ushort
+ {
+ /// <summary></summary>
+ KeyMake = 0,
+ /// <summary></summary>
+ KeyBreak = 1,
+ /// <summary></summary>
+ KeyE0 = 2,
+ /// <summary></summary>
+ KeyE1 = 4,
+ /// <summary></summary>
+ TerminalServerSetLED = 8,
+ /// <summary></summary>
+ TerminalServerShadow = 0x10,
+ /// <summary></summary>
+ TerminalServerVKPACKET = 0x20
+ }
+
+ /// <summary>
+ /// Enumeration contanining the command types to issue.
+ /// </summary>
+ public enum RawInputCommand
+ {
+ /// <summary>
+ /// Get input data.
+ /// </summary>
+ Input = 0x10000003,
+ /// <summary>
+ /// Get header data.
+ /// </summary>
+ Header = 0x10000005
+ }
+
+ [DllImport("user32.dll")]
+ public static extern bool RegisterRawInputDevices([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] RAWINPUTDEVICE[] pRawInputDevices, int uiNumDevices, int cbSize);
+
+ /// <summary>
+ /// Function to retrieve raw input data.
+ /// </summary>
+ /// <param name="hRawInput">Handle to the raw input.</param>
+ /// <param name="uiCommand">Command to issue when retrieving data.</param>
+ /// <param name="pData">Raw input data.</param>
+ /// <param name="pcbSize">Number of bytes in the array.</param>
+ /// <param name="cbSizeHeader">Size of the header.</param>
+ /// <returns>0 if successful if pData is null, otherwise number of bytes if pData is not null.</returns>
+ [DllImport("user32.dll")]
+ public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, out RawInput pData, ref int pcbSize, int cbSizeHeader);
+
+ public MouseWatcher(Form containingForm, Label display, AccelCharts accelCharts)
+ {
+ ContainingForm = containingForm;
+ Display = display;
+ AccelCharts = accelCharts;
+
+ RAWINPUTDEVICE device = new RAWINPUTDEVICE();
+ device.WindowHandle = ContainingForm.Handle;
+ device.UsagePage = HIDUsagePage.Generic;
+ device.Usage = HIDUsage.Mouse;
+ device.Flags = RawInputDeviceFlags.InputSink;
+
+ RAWINPUTDEVICE[] devices = new RAWINPUTDEVICE[1];
+ devices[0] = device;
+ RegisterRawInputDevices(devices, 1, Marshal.SizeOf(typeof(RAWINPUTDEVICE)));
+ }
+
+ Form ContainingForm { get; }
+
+ Label Display { get; }
+
+ AccelCharts AccelCharts { get; }
+
+ public void OnMouseMove(int x, int y)
+ {
+ Display.Text = $"Last (x, y): ({x}, {y})";
+ AccelCharts.MakeDots(x, y);
+ }
+
+ public void ReadMouseMove(Message message)
+ {
+ RawInput rawInput = new RawInput();
+ int outSize = 0;
+ int size = Marshal.SizeOf(typeof(RawInput));
+
+ outSize = GetRawInputData((IntPtr)message.LParam, RawInputCommand.Input, out rawInput, ref size, Marshal.SizeOf(typeof(RAWINPUTHEADER)));
+
+ if (rawInput.Data.Mouse.LastX != 0 || rawInput.Data.Mouse.LastY != 0)
+ {
+ OnMouseMove(rawInput.Data.Mouse.LastX, rawInput.Data.Mouse.LastY);
+ }
+
+ }
+ }
+}