diff --git a/Source/Examples/Tests/S04_Input_Logger.Designer.cs b/Source/Examples/Tests/S04_Input_Logger.Designer.cs index 9ee9573e..3d92d767 100644 --- a/Source/Examples/Tests/S04_Input_Logger.Designer.cs +++ b/Source/Examples/Tests/S04_Input_Logger.Designer.cs @@ -28,6 +28,7 @@ /// 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; } } \ No newline at end of file diff --git a/Source/Examples/Tests/S04_Input_Logger.cs b/Source/Examples/Tests/S04_Input_Logger.cs index d30721cd..ebd801a2 100644 --- a/Source/Examples/Tests/S04_Input_Logger.cs +++ b/Source/Examples/Tests/S04_Input_Logger.cs @@ -23,21 +23,11 @@ namespace Examples.Tests { InputDriver driver; Dictionary keyboardListBoxes = new Dictionary(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(); + } } } \ No newline at end of file diff --git a/Source/Examples/Tests/S04_Input_Logger.resx b/Source/Examples/Tests/S04_Input_Logger.resx index ff31a6db..ff50365d 100644 --- a/Source/Examples/Tests/S04_Input_Logger.resx +++ b/Source/Examples/Tests/S04_Input_Logger.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/Source/OpenTK/GameWindow.cs b/Source/OpenTK/GameWindow.cs index b23fcfb7..96a83a6f 100644 --- a/Source/OpenTK/GameWindow.cs +++ b/Source/OpenTK/GameWindow.cs @@ -354,7 +354,7 @@ namespace OpenTK public void ProcessEvents() { if (driver != null) - driver.ProcessEvents(); + driver.Poll(); glWindow.ProcessEvents(); } diff --git a/Source/OpenTK/Input/IInputDriver.cs b/Source/OpenTK/Input/IInputDriver.cs index df203e97..d2992c2e 100644 --- a/Source/OpenTK/Input/IInputDriver.cs +++ b/Source/OpenTK/Input/IInputDriver.cs @@ -12,7 +12,7 @@ namespace OpenTK.Input { public interface IInputDriver : IKeyboardDriver, IMouseDriver, IDisposable { - IList InputDevices { get; } - void ProcessEvents(); + //IList InputDevices { get; } + void Poll(); } } diff --git a/Source/OpenTK/Input/IMouse.cs b/Source/OpenTK/Input/IMouse.cs index 9ac2edf6..5223346d 100644 --- a/Source/OpenTK/Input/IMouse.cs +++ b/Source/OpenTK/Input/IMouse.cs @@ -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; diff --git a/Source/OpenTK/Input/Mouse.cs b/Source/OpenTK/Input/Mouse.cs index 49229933..c6147d51 100644 --- a/Source/OpenTK/Input/Mouse.cs +++ b/Source/OpenTK/Input/Mouse.cs @@ -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; } diff --git a/Source/OpenTK/InputDriver.cs b/Source/OpenTK/InputDriver.cs index 37d4918a..d2827610 100644 --- a/Source/OpenTK/InputDriver.cs +++ b/Source/OpenTK/InputDriver.cs @@ -45,11 +45,6 @@ namespace OpenTK #region --- IInputDriver Members --- - public IList InputDevices - { - get { return inputDriver.InputDevices; } - } - public IList 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() diff --git a/Source/OpenTK/Platform/Utilities.cs b/Source/OpenTK/Platform/Utilities.cs index 941722d4..a8b4f3e2 100644 --- a/Source/OpenTK/Platform/Utilities.cs +++ b/Source/OpenTK/Platform/Utilities.cs @@ -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 } } diff --git a/Source/OpenTK/Platform/Windows/API.cs b/Source/OpenTK/Platform/Windows/API.cs index 6756d519..43c1a6dd 100644 --- a/Source/OpenTK/Platform/Windows/API.cs +++ b/Source/OpenTK/Platform/Windows/API.cs @@ -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); - */ - - /// - /// 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. - /// - /// Pointer to an array of RawInput structures. - /// Number of RawInput structures pointed to by paRawInput. - /// Size, in bytes, of the RawInputHeader structure. - /// If successful, the function returns S_OK. Otherwise it returns an error value. [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 diff --git a/Source/OpenTK/Platform/Windows/WinRawInput.cs b/Source/OpenTK/Platform/Windows/WinRawInput.cs index 4238771b..be282b14 100644 --- a/Source/OpenTK/Platform/Windows/WinRawInput.cs +++ b/Source/OpenTK/Platform/Windows/WinRawInput.cs @@ -28,6 +28,7 @@ namespace OpenTK.Platform.Windows /// The total number of input devices connected to this system. /// 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; - /// /// Processes the input Windows Message, routing the data to the correct Keyboard, Mouse or HID. /// @@ -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.IInputDriver.InputDevices - { - get { throw new Exception("The method or operation is not implemented."); } - } - public IList 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). + + /// + /// Allocates a buffer for buffered reading of RawInput structs. Starts at 16*sizeof(RawInput) and + /// doubles the buffer every call thereafter. + /// + 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(); diff --git a/Source/OpenTK/Platform/Windows/WinRawMouse.cs b/Source/OpenTK/Platform/Windows/WinRawMouse.cs index 9b47d7c0..de9ecf2b 100644 --- a/Source/OpenTK/Platform/Windows/WinRawMouse.cs +++ b/Source/OpenTK/Platform/Windows/WinRawMouse.cs @@ -14,6 +14,9 @@ using Microsoft.Win32; namespace OpenTK.Platform.Windows { + /// + /// Contains methods to register for and process mouse WM_INPUT messages. + /// internal class WinRawMouse : IMouseDriver, IDisposable { private List mice = new List(); @@ -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 diff --git a/Source/OpenTK/Platform/X11/X11Input.cs b/Source/OpenTK/Platform/X11/X11Input.cs index bb7f2256..b5646fae 100644 --- a/Source/OpenTK/Platform/X11/X11Input.cs +++ b/Source/OpenTK/Platform/X11/X11Input.cs @@ -129,7 +129,7 @@ namespace OpenTK.Platform.X11 /// Consumes to keyboard, mouse, etc events, routing them to their /// respective drivers. /// - public void ProcessEvents() + public void Poll() { while (API.CheckMaskEvent(window.Display, EventMask.KeyReleaseMask | EventMask.KeyPressMask, ref e)) {