Windows raw input now works.

This commit is contained in:
the_fiddler 2007-09-22 13:13:17 +00:00
parent 0e3a330065
commit e277e3b272
13 changed files with 451 additions and 182 deletions

View file

@ -28,6 +28,7 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabControl = new System.Windows.Forms.TabControl();
this.Keyboard = new System.Windows.Forms.TabPage();
this.label4 = new System.Windows.Forms.Label();
@ -39,17 +40,22 @@
this.listBox2 = new System.Windows.Forms.ListBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.Mouse = new System.Windows.Forms.TabPage();
this.HID = new System.Windows.Forms.TabPage();
this.ChooseMouse = new System.Windows.Forms.ComboBox();
this.MouseButtons = new System.Windows.Forms.ListBox();
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.textBox4 = new System.Windows.Forms.TextBox();
this.MouseX = new System.Windows.Forms.Label();
this.MouseY = new System.Windows.Forms.Label();
this.MouseDeltaX = new System.Windows.Forms.Label();
this.MouseWheelText = new System.Windows.Forms.TextBox();
this.MouseWheel = new System.Windows.Forms.Label();
this.MouseDeltaY = new System.Windows.Forms.Label();
this.MouseDeltaX = new System.Windows.Forms.Label();
this.MouseY = new System.Windows.Forms.Label();
this.MouseX = new System.Windows.Forms.Label();
this.MouseDYText = new System.Windows.Forms.TextBox();
this.MouseDXText = new System.Windows.Forms.TextBox();
this.MouseYText = new System.Windows.Forms.TextBox();
this.MouseXText = new System.Windows.Forms.TextBox();
this.MouseButtons = new System.Windows.Forms.ListBox();
this.ChooseMouse = new System.Windows.Forms.ComboBox();
this.HID = new System.Windows.Forms.TabPage();
this.WheelDelta = new System.Windows.Forms.Label();
this.MouseWheelDelta = new System.Windows.Forms.TextBox();
this.PollTimer = new System.Windows.Forms.Timer(this.components);
this.tabControl.SuspendLayout();
this.Keyboard.SuspendLayout();
this.Mouse.SuspendLayout();
@ -156,14 +162,18 @@
// Mouse
//
this.Mouse.BackColor = System.Drawing.SystemColors.ControlLight;
this.Mouse.Controls.Add(this.MouseWheelDelta);
this.Mouse.Controls.Add(this.WheelDelta);
this.Mouse.Controls.Add(this.MouseWheelText);
this.Mouse.Controls.Add(this.MouseWheel);
this.Mouse.Controls.Add(this.MouseDeltaY);
this.Mouse.Controls.Add(this.MouseDeltaX);
this.Mouse.Controls.Add(this.MouseY);
this.Mouse.Controls.Add(this.MouseX);
this.Mouse.Controls.Add(this.textBox4);
this.Mouse.Controls.Add(this.textBox3);
this.Mouse.Controls.Add(this.textBox2);
this.Mouse.Controls.Add(this.textBox1);
this.Mouse.Controls.Add(this.MouseDYText);
this.Mouse.Controls.Add(this.MouseDXText);
this.Mouse.Controls.Add(this.MouseYText);
this.Mouse.Controls.Add(this.MouseXText);
this.Mouse.Controls.Add(this.MouseButtons);
this.Mouse.Controls.Add(this.ChooseMouse);
this.Mouse.Location = new System.Drawing.Point(4, 22);
@ -173,6 +183,109 @@
this.Mouse.TabIndex = 1;
this.Mouse.Text = "Mouse";
//
// MouseWheelText
//
this.MouseWheelText.Location = new System.Drawing.Point(80, 152);
this.MouseWheelText.Name = "MouseWheelText";
this.MouseWheelText.ReadOnly = true;
this.MouseWheelText.Size = new System.Drawing.Size(73, 20);
this.MouseWheelText.TabIndex = 11;
//
// MouseWheel
//
this.MouseWheel.AutoSize = true;
this.MouseWheel.Location = new System.Drawing.Point(4, 159);
this.MouseWheel.Name = "MouseWheel";
this.MouseWheel.Size = new System.Drawing.Size(38, 13);
this.MouseWheel.TabIndex = 10;
this.MouseWheel.Text = "Wheel";
//
// MouseDeltaY
//
this.MouseDeltaY.AutoSize = true;
this.MouseDeltaY.Location = new System.Drawing.Point(4, 132);
this.MouseDeltaY.Name = "MouseDeltaY";
this.MouseDeltaY.Size = new System.Drawing.Size(45, 13);
this.MouseDeltaY.TabIndex = 9;
this.MouseDeltaY.Text = "Delta Y:";
//
// MouseDeltaX
//
this.MouseDeltaX.AutoSize = true;
this.MouseDeltaX.Location = new System.Drawing.Point(4, 105);
this.MouseDeltaX.Name = "MouseDeltaX";
this.MouseDeltaX.Size = new System.Drawing.Size(45, 13);
this.MouseDeltaX.TabIndex = 8;
this.MouseDeltaX.Text = "Delta X:";
//
// MouseY
//
this.MouseY.AutoSize = true;
this.MouseY.Location = new System.Drawing.Point(4, 78);
this.MouseY.Name = "MouseY";
this.MouseY.Size = new System.Drawing.Size(57, 13);
this.MouseY.TabIndex = 7;
this.MouseY.Text = "Position Y:";
//
// MouseX
//
this.MouseX.AutoSize = true;
this.MouseX.Location = new System.Drawing.Point(4, 51);
this.MouseX.Name = "MouseX";
this.MouseX.Size = new System.Drawing.Size(57, 13);
this.MouseX.TabIndex = 6;
this.MouseX.Text = "Position X:";
//
// MouseDYText
//
this.MouseDYText.Location = new System.Drawing.Point(80, 125);
this.MouseDYText.Name = "MouseDYText";
this.MouseDYText.ReadOnly = true;
this.MouseDYText.Size = new System.Drawing.Size(73, 20);
this.MouseDYText.TabIndex = 5;
//
// MouseDXText
//
this.MouseDXText.Location = new System.Drawing.Point(80, 98);
this.MouseDXText.Name = "MouseDXText";
this.MouseDXText.ReadOnly = true;
this.MouseDXText.Size = new System.Drawing.Size(73, 20);
this.MouseDXText.TabIndex = 4;
//
// MouseYText
//
this.MouseYText.Location = new System.Drawing.Point(80, 71);
this.MouseYText.Name = "MouseYText";
this.MouseYText.ReadOnly = true;
this.MouseYText.Size = new System.Drawing.Size(73, 20);
this.MouseYText.TabIndex = 3;
//
// MouseXText
//
this.MouseXText.Location = new System.Drawing.Point(80, 44);
this.MouseXText.Name = "MouseXText";
this.MouseXText.ReadOnly = true;
this.MouseXText.Size = new System.Drawing.Size(73, 20);
this.MouseXText.TabIndex = 2;
//
// MouseButtons
//
this.MouseButtons.FormattingEnabled = true;
this.MouseButtons.Location = new System.Drawing.Point(256, 44);
this.MouseButtons.Name = "MouseButtons";
this.MouseButtons.Size = new System.Drawing.Size(160, 134);
this.MouseButtons.TabIndex = 1;
//
// ChooseMouse
//
this.ChooseMouse.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ChooseMouse.FormattingEnabled = true;
this.ChooseMouse.Location = new System.Drawing.Point(7, 7);
this.ChooseMouse.Name = "ChooseMouse";
this.ChooseMouse.Size = new System.Drawing.Size(409, 21);
this.ChooseMouse.TabIndex = 0;
this.ChooseMouse.SelectedIndexChanged += new System.EventHandler(this.ChooseMouse_SelectedIndexChanged);
//
// HID
//
this.HID.Location = new System.Drawing.Point(4, 22);
@ -183,90 +296,26 @@
this.HID.Text = "HID";
this.HID.UseVisualStyleBackColor = true;
//
// ChooseMouse
// WheelDelta
//
this.ChooseMouse.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ChooseMouse.FormattingEnabled = true;
this.ChooseMouse.Location = new System.Drawing.Point(7, 7);
this.ChooseMouse.Name = "ChooseMouse";
this.ChooseMouse.Size = new System.Drawing.Size(409, 21);
this.ChooseMouse.TabIndex = 0;
this.WheelDelta.AutoSize = true;
this.WheelDelta.Location = new System.Drawing.Point(4, 185);
this.WheelDelta.Name = "WheelDelta";
this.WheelDelta.Size = new System.Drawing.Size(69, 13);
this.WheelDelta.TabIndex = 12;
this.WheelDelta.Text = "Wheel Delta:";
//
// MouseButtons
// MouseWheelDelta
//
this.MouseButtons.FormattingEnabled = true;
this.MouseButtons.Location = new System.Drawing.Point(7, 197);
this.MouseButtons.Name = "MouseButtons";
this.MouseButtons.Size = new System.Drawing.Size(409, 147);
this.MouseButtons.TabIndex = 1;
this.MouseWheelDelta.Location = new System.Drawing.Point(80, 178);
this.MouseWheelDelta.Name = "MouseWheelDelta";
this.MouseWheelDelta.ReadOnly = true;
this.MouseWheelDelta.Size = new System.Drawing.Size(73, 20);
this.MouseWheelDelta.TabIndex = 13;
//
// textBox1
// PollTimer
//
this.textBox1.Location = new System.Drawing.Point(66, 44);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(73, 20);
this.textBox1.TabIndex = 2;
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(66, 71);
this.textBox2.Name = "textBox2";
this.textBox2.ReadOnly = true;
this.textBox2.Size = new System.Drawing.Size(73, 20);
this.textBox2.TabIndex = 3;
//
// textBox3
//
this.textBox3.Location = new System.Drawing.Point(66, 98);
this.textBox3.Name = "textBox3";
this.textBox3.ReadOnly = true;
this.textBox3.Size = new System.Drawing.Size(73, 20);
this.textBox3.TabIndex = 4;
//
// textBox4
//
this.textBox4.Location = new System.Drawing.Point(66, 125);
this.textBox4.Name = "textBox4";
this.textBox4.ReadOnly = true;
this.textBox4.Size = new System.Drawing.Size(73, 20);
this.textBox4.TabIndex = 5;
//
// MouseX
//
this.MouseX.AutoSize = true;
this.MouseX.Location = new System.Drawing.Point(4, 51);
this.MouseX.Name = "MouseX";
this.MouseX.Size = new System.Drawing.Size(57, 13);
this.MouseX.TabIndex = 6;
this.MouseX.Text = "Position X:";
//
// MouseY
//
this.MouseY.AutoSize = true;
this.MouseY.Location = new System.Drawing.Point(4, 78);
this.MouseY.Name = "MouseY";
this.MouseY.Size = new System.Drawing.Size(57, 13);
this.MouseY.TabIndex = 7;
this.MouseY.Text = "Position Y:";
//
// MouseDeltaX
//
this.MouseDeltaX.AutoSize = true;
this.MouseDeltaX.Location = new System.Drawing.Point(4, 105);
this.MouseDeltaX.Name = "MouseDeltaX";
this.MouseDeltaX.Size = new System.Drawing.Size(45, 13);
this.MouseDeltaX.TabIndex = 8;
this.MouseDeltaX.Text = "Delta X:";
//
// MouseDeltaY
//
this.MouseDeltaY.AutoSize = true;
this.MouseDeltaY.Location = new System.Drawing.Point(4, 132);
this.MouseDeltaY.Name = "MouseDeltaY";
this.MouseDeltaY.Size = new System.Drawing.Size(45, 13);
this.MouseDeltaY.TabIndex = 9;
this.MouseDeltaY.Text = "Delta Y:";
this.PollTimer.Interval = 10;
//
// S04_Input_Logger
//
@ -306,10 +355,15 @@
private System.Windows.Forms.Label MouseDeltaX;
private System.Windows.Forms.Label MouseY;
private System.Windows.Forms.Label MouseX;
private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox MouseDYText;
private System.Windows.Forms.TextBox MouseDXText;
private System.Windows.Forms.TextBox MouseYText;
private System.Windows.Forms.TextBox MouseXText;
private System.Windows.Forms.TextBox MouseWheelText;
private System.Windows.Forms.Label MouseWheel;
private System.Windows.Forms.TextBox MouseWheelDelta;
private System.Windows.Forms.Label WheelDelta;
private System.Windows.Forms.Timer PollTimer;
}
}

View file

@ -23,21 +23,11 @@ namespace Examples.Tests
{
InputDriver driver;
Dictionary<IntPtr, ListBox> keyboardListBoxes = new Dictionary<IntPtr, ListBox>(4);
bool stop_polling;
public S04_Input_Logger()
{
InitializeComponent();
Application.Idle += new EventHandler(Application_Idle);
}
void Application_Idle(object sender, EventArgs e)
{
// Update mouse coordinates.
textBox1.Text = driver.Mouse[ChooseMouse.SelectedIndex].X.ToString();
textBox2.Text = driver.Mouse[ChooseMouse.SelectedIndex].Y.ToString();
textBox3.Text = driver.Mouse[ChooseMouse.SelectedIndex].DeltaX.ToString();
textBox4.Text = driver.Mouse[ChooseMouse.SelectedIndex].DeltaY.ToString();
}
protected override void OnLoad(EventArgs e)
@ -46,8 +36,8 @@ namespace Examples.Tests
WindowInfo info = new WindowInfo(this);
driver = new InputDriver(info);
Debug.Print("Keyboard count: {0}", driver.Keyboard.Count);
Debug.Print("Mouse count: {0}", driver.Mouse.Count);
Trace.WriteLine(String.Format("Keyboard count: {0}", driver.Keyboard.Count));
Trace.WriteLine(String.Format("Mouse count: {0}", driver.Mouse.Count));
switch (driver.Keyboard.Count)
{
@ -87,15 +77,15 @@ namespace Examples.Tests
}
// Add available mice to the mouse input logger.
int i = 0;
foreach (Mouse m in driver.Mouse)
{
ChooseMouse.Items.Add(String.Format("Mouse {0} ({1})", ++i, m.Description));
m.ButtonDown += LogMouseButtonDown;
m.ButtonUp += LogMouseButtonUp;
}
if (i > 0)
if (driver.Mouse.Count > 0)
{
int i = 0;
foreach (Mouse m in driver.Mouse)
{
ChooseMouse.Items.Add(String.Format("Mouse {0} ({1})", ++i, m.Description));
m.ButtonDown += LogMouseButtonDown;
m.ButtonUp += LogMouseButtonUp;
}
ChooseMouse.SelectedIndex = 0;
}
@ -104,29 +94,46 @@ namespace Examples.Tests
k.KeyDown += new KeyDownEvent(LogKeyDown);
k.KeyUp += new KeyUpEvent(LogKeyUp);
}
//PollTimer.Tick += new EventHandler(PollTimer_Tick);
//PollTimer.Start();
Application.Idle += new EventHandler(Application_Idle);
}
void Application_Idle(object sender, EventArgs e)
{
// Update mouse coordinates.
MouseXText.Text = driver.Mouse[ChooseMouse.SelectedIndex].X.ToString();
MouseYText.Text = driver.Mouse[ChooseMouse.SelectedIndex].Y.ToString();
MouseDXText.Text = driver.Mouse[ChooseMouse.SelectedIndex].XDelta.ToString();
MouseDYText.Text = driver.Mouse[ChooseMouse.SelectedIndex].YDelta.ToString();
MouseWheelText.Text = driver.Mouse[ChooseMouse.SelectedIndex].Wheel.ToString();
//MouseWheelDelta.Text = driver.Mouse[ChooseMouse.SelectedIndex].WheelDelta.ToString();
}
void LogMouseButtonDown(IMouse sender, MouseButton button)
{
Debug.Print("Mouse button down: {0} on device: {1}", button, sender.DeviceID);
MouseButtons.Items.Add(button);
Trace.WriteLine(String.Format("Mouse button down: {0} on device: {1}", button, sender.DeviceID));
if (sender.DeviceID == driver.Mouse[ChooseMouse.SelectedIndex].DeviceID)
MouseButtons.Items.Add(button);
}
void LogMouseButtonUp(IMouse sender, MouseButton button)
{
Debug.Print("Mouse button up: {0} on device: {1}", button, sender.DeviceID);
MouseButtons.Items.Remove(button);
Trace.WriteLine(String.Format("Mouse button up: {0} on device: {1}", button, sender.DeviceID));
if (sender.DeviceID == driver.Mouse[ChooseMouse.SelectedIndex].DeviceID)
MouseButtons.Items.Remove(button);
}
void LogKeyDown(object sender, Key key)
{
Debug.Print("Key down: {0} on device: {1}", key, (sender as Keyboard).DeviceID);
Trace.WriteLine(String.Format("Key down: {0} on device: {1}", key, (sender as Keyboard).DeviceID));
keyboardListBoxes[(sender as Keyboard).DeviceID].Items.Add(key);
}
void LogKeyUp(object sender, Key key)
{
Debug.Print("Key up: {0} on device: {1}", key, (sender as Keyboard).DeviceID);
Trace.WriteLine(String.Format("Key up: {0} on device: {1}", key, (sender as Keyboard).DeviceID));
keyboardListBoxes[(sender as Keyboard).DeviceID].Items.Remove(key);
}
@ -138,5 +145,10 @@ namespace Examples.Tests
}
#endregion
private void ChooseMouse_SelectedIndexChanged(object sender, EventArgs e)
{
MouseButtons.Items.Clear();
}
}
}

View file

@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="PollTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -354,7 +354,7 @@ namespace OpenTK
public void ProcessEvents()
{
if (driver != null)
driver.ProcessEvents();
driver.Poll();
glWindow.ProcessEvents();
}

View file

@ -12,7 +12,7 @@ namespace OpenTK.Input
{
public interface IInputDriver : IKeyboardDriver, IMouseDriver, IDisposable
{
IList<IInputDevice> InputDevices { get; }
void ProcessEvents();
//IList<IInputDevice> InputDevices { get; }
void Poll();
}
}

View file

@ -18,8 +18,8 @@ namespace OpenTK.Input
int Wheel { get; }
int X { get; }
int Y { get; }
int DeltaX { get; }
int DeltaY { get; }
int XDelta { get; }
int YDelta { get; }
//event MouseMoveEvent Move;
event MouseButtonDownEvent ButtonDown;

View file

@ -16,7 +16,7 @@ namespace OpenTK.Input
private int numButtons, numWheels;
private IntPtr id;
private bool[] button = new bool[(int)MouseButton.LastButton];
private int wheel, x, y, delta_x, delta_y;
private int wheel, x, y, wheel_delta, delta_x, delta_y;
#region --- IInputDevice Members ---
@ -56,7 +56,24 @@ namespace OpenTK.Input
public int Wheel
{
get { return wheel; }
internal set { wheel = value; }
internal set
{
wheel = value;
}
}
internal int WheelDelta
{
get
{
int delta = wheel_delta;
//wheel_delta = 0;
return delta;
}
set
{
wheel_delta = value;
}
}
public int X
@ -71,13 +88,13 @@ namespace OpenTK.Input
internal set { y = value; }
}
public int DeltaX
public int XDelta
{
get { return delta_x; }
internal set { delta_x = value; }
}
public int DeltaY
public int YDelta
{
get { return delta_y; }
internal set { delta_y = value; }

View file

@ -45,11 +45,6 @@ namespace OpenTK
#region --- IInputDriver Members ---
public IList<IInputDevice> InputDevices
{
get { return inputDriver.InputDevices; }
}
public IList<Keyboard> Keyboard
{
get { return inputDriver.Keyboard; }
@ -60,9 +55,9 @@ namespace OpenTK
get { return inputDriver.Mouse; }
}
public void ProcessEvents()
public void Poll()
{
inputDriver.ProcessEvents();
inputDriver.Poll();
}
/*
int IMouseDriver.RegisterDevices()

View file

@ -186,5 +186,48 @@ namespace OpenTK.Platform
}
}
}
#region public bool IsIdle
interface IIsIdle { bool IsIdle { get; } }
class X11IsIdle : IIsIdle
{
public bool IsIdle
{
get
{
return X11.API.Pending(IntPtr.Zero) == 0;
}
}
}
class WindowsIsIdle : IIsIdle
{
Windows.MSG msg;
public bool IsIdle
{
get
{
return !Windows.API.PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0);
}
}
}
static IIsIdle isIdleImpl =
System.Environment.OSVersion.Platform == PlatformID.Unix ?
(IIsIdle)new X11IsIdle() : (IIsIdle)new WindowsIsIdle();
public static bool IsIdle
{
get
{
return isIdleImpl.IsIdle;
}
}
#endregion
}
}

View file

@ -546,27 +546,16 @@ namespace OpenTK.Platform.Windows
[DllImport("user32.dll", SetLastError = true)]
public static extern LRESULT DefRawInputProc(RawInput[] RawInput, INT Input, UINT SizeHeader);
/*
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll", SetLastError = true)]
public static extern LRESULT DefRawInputProc(RawInput[] RawInput, INT Input, INT SizeHeader);
*/
/// <summary>
/// calls the default raw input procedure to provide default processing for
/// any raw input messages that an application does not process.
/// This function ensures that every message is processed.
/// DefRawInputProc is called with the same parameters received by the window procedure.
/// </summary>
/// <param name="RawInput">Pointer to an array of RawInput structures.</param>
/// <param name="Input">Number of RawInput structures pointed to by paRawInput.</param>
/// <param name="SizeHeader">Size, in bytes, of the RawInputHeader structure.</param>
/// <returns>If successful, the function returns S_OK. Otherwise it returns an error value.</returns>
[CLSCompliant(false)]
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll", SetLastError = true)]
unsafe public static extern LRESULT DefRawInputProc(ref RawInput RawInput, INT Input, UINT SizeHeader);
[CLSCompliant(false)]
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll", SetLastError = true)]
unsafe public static extern LRESULT DefRawInputProc(IntPtr RawInput, INT Input, UINT SizeHeader);
#endregion
#region RegisterRawInputDevices
@ -639,6 +628,14 @@ namespace OpenTK.Platform.Windows
[In] INT SizeHeader
);
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll", SetLastError = true)]
public static extern INT GetRawInputBuffer(
[Out] IntPtr Data,
[In, Out] ref INT Size,
[In] INT SizeHeader
);
#endregion
#region GetRegisteredRawInputDevices
@ -965,6 +962,37 @@ namespace OpenTK.Platform.Windows
INT SizeHeader
);
#endregion
#region IntPtr NextRawInputStructure(IntPtr data)
/* From winuser.h
#ifdef _WIN64
#define RAWINPUT_ALIGN(x) (((x) + sizeof(QWORD) - 1) & ~(sizeof(QWORD) - 1))
#else // _WIN64
#define RAWINPUT_ALIGN(x) (((x) + sizeof(DWORD) - 1) & ~(sizeof(DWORD) - 1))
#endif // _WIN64
#define NEXTRAWINPUTBLOCK(ptr) ((PRAWINPUT)RAWINPUT_ALIGN((ULONG_PTR)((PBYTE)(ptr) + (ptr)->header.dwSize)))
*/
public static IntPtr NextRawInputStructure(IntPtr data)
{
unsafe
{
return RawInputAlign((IntPtr)(((byte*)data) + RawInputHeaderSize));
}
}
private static IntPtr RawInputAlign(IntPtr data)
{
unsafe
{
return (IntPtr)(((byte*)data) + ((IntPtr.Size - 1) & ~(IntPtr.Size - 1)));
}
}
#endregion
#endregion

View file

@ -28,6 +28,7 @@ namespace OpenTK.Platform.Windows
/// The total number of input devices connected to this system.
/// </summary>
private static int deviceCount;
int rawInputStructSize = API.RawInputSize;
private WinRawKeyboard keyboardDriver;
private WinRawMouse mouseDriver;
@ -45,6 +46,8 @@ namespace OpenTK.Platform.Windows
mouseDriver = new WinRawMouse(this.Handle);
Debug.Unindent();
AllocateBuffer();
}
#endregion
@ -64,8 +67,6 @@ namespace OpenTK.Platform.Windows
#region protected override void WndProc(ref Message msg)
int size = 0;
/// <summary>
/// Processes the input Windows Message, routing the data to the correct Keyboard, Mouse or HID.
/// </summary>
@ -75,7 +76,7 @@ namespace OpenTK.Platform.Windows
switch ((WindowMessage)msg.Msg)
{
case WindowMessage.INPUT:
size = 0;
int size = 0;
// Get the size of the input data
API.GetRawInputData(msg.LParam, GetRawInputDataEnum.INPUT,
IntPtr.Zero, ref size, API.RawInputHeaderSize);
@ -84,7 +85,6 @@ namespace OpenTK.Platform.Windows
//{
// throw new ApplicationException("Critical error when processing raw windows input.");
//}
if (size == API.GetRawInputData(msg.LParam, GetRawInputDataEnum.INPUT,
data, ref size, API.RawInputHeaderSize))
{
@ -118,14 +118,14 @@ namespace OpenTK.Platform.Windows
case WindowMessage.CLOSE:
case WindowMessage.DESTROY:
Debug.Print("Input window detached from parent {0}.", Handle);
ReleaseHandle();
break;
Debug.Print("Input window detached from parent {0}.", Handle);
ReleaseHandle();
break;
case WindowMessage.QUIT:
Debug.WriteLine("Input window quit.");
this.Dispose();
break;
Debug.WriteLine("Input window quit.");
this.Dispose();
break;
}
base.WndProc(ref msg);
@ -135,11 +135,6 @@ namespace OpenTK.Platform.Windows
#region --- IInputDriver Members ---
IList<Input.IInputDevice> Input.IInputDriver.InputDevices
{
get { throw new Exception("The method or operation is not implemented."); }
}
public IList<Keyboard> Keyboard
{
get { return keyboardDriver.Keyboard; }
@ -150,9 +145,85 @@ namespace OpenTK.Platform.Windows
get { return mouseDriver.Mouse; }
}
public void ProcessEvents()
int allocated_buffer_size; // rin_data size in bytes.
IntPtr rin_data; // Unmanaged buffer with grow-only behavior. Freed at Dispose(bool).
/// <summary>
/// Allocates a buffer for buffered reading of RawInput structs. Starts at 16*sizeof(RawInput) and
/// doubles the buffer every call thereafter.
/// </summary>
private void AllocateBuffer()
{
// Do nothing, the WndProc is automatically notified of new events (sub-classing magic).
// Find the size of the buffer (grow-only).
if (allocated_buffer_size == 0)
{
allocated_buffer_size = 16536 * rawInputStructSize;
}
else
{
allocated_buffer_size *= 2;
}
// Allocate the new buffer.
if (rin_data != IntPtr.Zero)
{
Marshal.FreeHGlobal(rin_data);
}
rin_data = Marshal.AllocHGlobal(allocated_buffer_size);
if (rin_data == IntPtr.Zero)
{
throw new OutOfMemoryException(String.Format(
"Failed to allocate {0} bytes for raw input structures.", allocated_buffer_size));
}
}
public void Poll()
{
return;
// We will do a buffered read for all input devices and route the RawInput structures
// to the correct 'ProcessData' handlers. First, we need to find out the size of the
// buffer to allocate for the structures. Then we allocate the buffer and read the
// structures, calling the correct handler for each one. Last, we free the allocated
// buffer.
while (true)
{
// Iterate reading all available RawInput structures and routing them to their respective
// handlers.
int num = API.GetRawInputBuffer(rin_data, ref allocated_buffer_size, API.RawInputHeaderSize);
if (num == 0)
return;
else if (num < 0)
{
/*int error = Marshal.GetLastWin32Error();
if (error == 122)
{
// Enlarge the buffer, it was too small.
AllocateBuffer();
}
else
{
throw new ApplicationException(String.Format(
"GetRawInputBuffer failed with code: {0}", error));
}*/
Debug.Print("GetRawInputBuffer failed with code: {0}", Marshal.GetLastWin32Error());
//AllocateBuffer();
return;
}
IntPtr next_rin = rin_data;
int i = num;
while (--i > 0)
{
RawInput rin;
rin = (RawInput)Marshal.PtrToStructure(next_rin, typeof(RawInput));
if (rin.Header.Type == RawInputDeviceType.KEYBOARD)
keyboardDriver.ProcessKeyboardEvent(rin);
else if (rin.Header.Type == RawInputDeviceType.MOUSE)
mouseDriver.ProcessEvent(rin);
next_rin = API.NextRawInputStructure(next_rin);
}
API.DefRawInputProc(rin_data, num, (uint)API.RawInputHeaderSize);
}
}
#endregion
@ -171,6 +242,11 @@ namespace OpenTK.Platform.Windows
{
if (!disposed)
{
if (rin_data != IntPtr.Zero)
{
Marshal.FreeHGlobal(rin_data);
}
if (manual)
{
keyboardDriver.Dispose();

View file

@ -14,6 +14,9 @@ using Microsoft.Win32;
namespace OpenTK.Platform.Windows
{
/// <summary>
/// Contains methods to register for and process mouse WM_INPUT messages.
/// </summary>
internal class WinRawMouse : IMouseDriver, IDisposable
{
private List<Mouse> mice = new List<Mouse>();
@ -47,6 +50,8 @@ namespace OpenTK.Platform.Windows
get { return mice; }
}
#region public int RegisterDevices()
public int RegisterDevices()
{
int count = WinRawInput.DeviceCount;
@ -122,6 +127,8 @@ namespace OpenTK.Platform.Windows
#endregion
#endregion
#region internal void RegisterRawDevice(OpenTK.Input.Mouse mouse)
internal void RegisterRawDevice(OpenTK.Input.Mouse mouse)
@ -164,6 +171,7 @@ namespace OpenTK.Platform.Windows
{
return m.DeviceID == rin.Header.Device;
});
if (mouse == null && mice.Count > 0) mouse = mice[0];
switch (rin.Header.Type)
{
@ -179,24 +187,28 @@ namespace OpenTK.Platform.Windows
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0) mouse[MouseButton.Button2] = true;
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0) mouse[MouseButton.Button2] = false;
if (rin.Data.Mouse.ButtonFlags == RawInputMouseState.WHEEL)
{
mouse.Wheel += rin.Data.Mouse.ButtonData;
//mouse.WheelDelta = rin.Data.Mouse.ButtonData;
//mouse.Wheel += rin.Data.Mouse.ButtonData;
mouse.WheelDelta = rin.Data.Mouse.ButtonData > 0 ? 1 : -1;
mouse.Wheel += mouse.WheelDelta;
}
if (rin.Data.Mouse.Flags == RawMouseFlags.MOUSE_MOVE_ABSOLUTE)
{
mouse.DeltaX = rin.Data.Mouse.LastX - mouse.X;
mouse.DeltaY = rin.Data.Mouse.LastY - mouse.Y;
mouse.XDelta = rin.Data.Mouse.LastX - mouse.X;
mouse.YDelta = rin.Data.Mouse.LastY - mouse.Y;
mouse.X = rin.Data.Mouse.LastX;
mouse.Y = rin.Data.Mouse.LastY;
}
else if (rin.Data.Mouse.Flags == RawMouseFlags.MOUSE_MOVE_RELATIVE)
{
mouse.DeltaX = rin.Data.Mouse.LastX;
mouse.DeltaY = rin.Data.Mouse.LastY;
mouse.X += mouse.DeltaX;
mouse.Y += mouse.DeltaY;
mouse.XDelta = rin.Data.Mouse.LastX;
mouse.YDelta = rin.Data.Mouse.LastY;
mouse.X += mouse.XDelta;
mouse.Y += mouse.YDelta;
}
return false;
@ -208,11 +220,40 @@ namespace OpenTK.Platform.Windows
#endregion
#region public void Poll()
public void Poll()
{
}
#endregion
#region --- IDisposable Members ---
private bool disposed;
public void Dispose()
{
//throw new Exception("The method or operation is not implemented.");
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool manual)
{
if (!disposed)
{
if (manual)
{
mice.Clear();
}
disposed = true;
}
}
~WinRawMouse()
{
Dispose(false);
}
#endregion

View file

@ -129,7 +129,7 @@ namespace OpenTK.Platform.X11
/// Consumes to keyboard, mouse, etc events, routing them to their
/// respective drivers.
/// </summary>
public void ProcessEvents()
public void Poll()
{
while (API.CheckMaskEvent(window.Display, EventMask.KeyReleaseMask | EventMask.KeyPressMask, ref e))
{