Implemented raw keyboard input for Windows. Improved the interface for receiving input. Moved raw input window to its own thread.

This commit is contained in:
the_fiddler 2010-10-22 14:57:06 +00:00
parent 75c71107a3
commit 2430f82ff7
8 changed files with 328 additions and 315 deletions

View file

@ -0,0 +1,41 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2010 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Input
{
// Defines the interface for a 2nd generation input driver.
interface IInputDriver2
{
IMouseDriver MouseDriver { get; }
IKeyboardDriver KeyboardDriver { get; }
IJoystickDriver JoystickDriver { get; }
}
}

View file

@ -1,146 +0,0 @@
#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using OpenTK.Input;
using OpenTK.Platform;
namespace OpenTK
{
internal class InputDriver : IInputDriver
{
private IInputDriver inputDriver;
#region --- Constructors ---
public InputDriver(GameWindow parent)
{
if (parent == null)
throw new ArgumentException("A valid window (IWindowInfo) must be specified to construct an InputDriver");
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32Windows:
case PlatformID.Win32NT:
case PlatformID.Win32S:
case PlatformID.WinCE:
if (Environment.OSVersion.Version.Major > 5 ||
(Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1))
{
inputDriver = new OpenTK.Platform.Windows.WinRawInput((OpenTK.Platform.Windows.WinWindowInfo)parent.WindowInfo);
}
else
{
// Legacy or unknown windows version:
inputDriver = new OpenTK.Platform.Windows.WMInput((OpenTK.Platform.Windows.WinWindowInfo)parent.WindowInfo);
}
break;
case PlatformID.Unix:
// TODO: Input is currently handled asychronously by the driver in X11GLNative.
//inputDriver = new OpenTK.Platform.X11.X11Input(parent.WindowInfo);
break;
default:
throw new PlatformNotSupportedException(
"Input handling is not supported on the current platform. Please report the problem to http://opentk.sourceforge.net");
}
}
#endregion
#region --- IInputDriver Members ---
public void Poll()
{
inputDriver.Poll();
}
#endregion
#region --- IKeyboardDriver Members ---
public IList<KeyboardDevice> Keyboard
{
get { return inputDriver.Keyboard; }
}
public KeyboardState GetState()
{
return (inputDriver as IKeyboardDriver).GetState();
}
public KeyboardState GetState(int index)
{
return (inputDriver as IKeyboardDriver).GetState(index);
}
#endregion
#region --- IMouseDriver Members ---
public IList<MouseDevice> Mouse
{
get { return inputDriver.Mouse; }
}
MouseState IMouseDriver.GetState()
{
throw new NotImplementedException();
}
MouseState IMouseDriver.GetState(int index)
{
throw new NotImplementedException();
}
#endregion
#region --- IJoystickDriver Members ---
public IList<JoystickDevice> Joysticks
{
get { return inputDriver.Joysticks; }
}
#endregion
#region --- IDisposable Members ---
private bool disposed;
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool manual)
{
if (!disposed)
{
if (manual)
{
inputDriver.Dispose();
}
disposed = true;
}
}
~InputDriver()
{
this.Dispose(false);
}
#endregion
}
}

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup> <PropertyGroup>
<ProjectType>Local</ProjectType> <ProjectType>Local</ProjectType>
@ -131,6 +131,7 @@
<Compile Include="DisplayDevice.cs"> <Compile Include="DisplayDevice.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Input\IInputDriver2.cs" />
<Compile Include="WindowBorder.cs"> <Compile Include="WindowBorder.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
@ -551,9 +552,6 @@
<Compile Include="Input\MouseState.cs"> <Compile Include="Input\MouseState.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Input\InputDriver.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Input\GamePadState.cs"> <Compile Include="Input\GamePadState.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>

View file

@ -1,7 +1,28 @@
#region --- License --- #region License
/* Copyright (c) 2007 Stefanos Apostolopoulos //
* See license.txt for license information // The Open Toolkit Library License
*/ //
// Copyright (c) 2006 - 2010 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion #endregion
using System; using System;
@ -16,7 +37,7 @@ using System.Drawing;
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
// Input driver for legacy (pre XP) Windows platforms. // Input driver for legacy (pre XP) Windows platforms.
sealed class WMInput : System.Windows.Forms.NativeWindow, IInputDriver sealed class WMInput : System.Windows.Forms.NativeWindow, IInputDriver, IInputDriver2
{ {
#region --- Fields --- #region --- Fields ---
@ -315,5 +336,20 @@ namespace OpenTK.Platform.Windows
} }
#endregion #endregion
public IMouseDriver MouseDriver
{
get { throw new NotImplementedException(); }
}
public IKeyboardDriver KeyboardDriver
{
get { throw new NotImplementedException(); }
}
public IJoystickDriver JoystickDriver
{
get { return joystick_driver; }
}
} }
} }

View file

@ -36,6 +36,9 @@ namespace OpenTK.Platform.Windows
class WinFactory : IPlatformFactory class WinFactory : IPlatformFactory
{ {
readonly object SyncRoot = new object();
IInputDriver2 inputDriver;
#region IPlatformFactory Members #region IPlatformFactory Members
public virtual INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device) public virtual INativeWindow CreateNativeWindow(int x, int y, int width, int height, string title, GraphicsMode mode, GameWindowFlags options, DisplayDevice device)
@ -73,22 +76,34 @@ namespace OpenTK.Platform.Windows
public virtual OpenTK.Input.IKeyboardDriver CreateKeyboardDriver() public virtual OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
{ {
throw new NotImplementedException();
// If Windows version is NT5 or higher, we are able to use raw input. return InputDriver.KeyboardDriver;
if (System.Environment.OSVersion.Version.Major >= 5)
return new WinRawKeyboard();
else
return new WMInput(null);
} }
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver() public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
{ {
if (System.Environment.OSVersion.Version.Major >= 5) return InputDriver.MouseDriver;
return new WinRawMouse();
else
return new WMInput(null);
} }
#endregion #endregion
IInputDriver2 InputDriver
{
get
{
lock (SyncRoot)
{
if (inputDriver == null)
{
// If Windows version is NT5 or higher, we are able to use raw input.
if (System.Environment.OSVersion.Version.Major >= 5)
inputDriver = new WinRawInput();
else
inputDriver = new WMInput(null);
}
return inputDriver;
}
}
}
} }
} }

View file

@ -1,7 +1,28 @@
#region --- License --- #region License
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos //
* See license.txt for license info // The Open Toolkit Library License
*/ //
// Copyright (c) 2006 - 2010 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion #endregion
#region --- Using directives --- #region --- Using directives ---
@ -13,49 +34,51 @@ using System.Runtime.InteropServices;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Forms; using System.Windows.Forms;
using OpenTK.Input; using OpenTK.Input;
using System.Threading;
#endregion #endregion
namespace OpenTK.Platform.Windows namespace OpenTK.Platform.Windows
{ {
// Not complete. // Not complete.
sealed class WinRawInput : System.Windows.Forms.NativeWindow, IInputDriver sealed class WinRawInput : IInputDriver, IInputDriver2
{ {
// Input event data. // Input event data.
RawInput data = new RawInput(); static RawInput data = new RawInput();
// The total number of input devices connected to this system. static readonly int rawInputStructSize = API.RawInputSize;
static int deviceCount; static readonly Thread InputThread = new Thread(ProcessEvents);
int rawInputStructSize = API.RawInputSize;
private WinRawKeyboard keyboardDriver; static WinRawKeyboard keyboardDriver;
private WinRawMouse mouseDriver; static WinRawMouse mouseDriver;
static readonly WinMMJoystick joystickDriver = new WinMMJoystick();
#region --- Constructors --- static INativeWindow Native;
static WinWindowInfo Parent { get { return Native.WindowInfo as WinWindowInfo; } }
static readonly WindowProcedure WndProc = WindowProcedureImplementation;
static IntPtr OldWndProc;
internal WinRawInput(WinWindowInfo parent) #region Constructors
public WinRawInput()
{ {
Debug.WriteLine("Initalizing windows raw input driver."); InputThread.IsBackground = true;
Debug.Indent(); InputThread.Start();
AssignHandle(parent.WindowHandle); while (mouseDriver == null || keyboardDriver == null)
WinWindowInfo win = new WinWindowInfo(this.Handle, parent); Thread.Sleep(0);
Debug.Print("Input window attached to parent {0}", parent);
keyboardDriver = new WinRawKeyboard(this.Handle);
mouseDriver = new WinRawMouse();
Debug.Unindent();
//AllocateBuffer();
} }
#endregion #endregion
#region internal static int DeviceCount #region Public Members
internal static int DeviceCount #region DeviceCount
public static int DeviceCount
{ {
get get
{ {
int deviceCount = 0;
Functions.GetRawInputDeviceList(null, ref deviceCount, API.RawInputDeviceListSize); Functions.GetRawInputDeviceList(null, ref deviceCount, API.RawInputDeviceListSize);
return deviceCount; return deviceCount;
} }
@ -63,72 +86,103 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region protected override void WndProc(ref Message msg) #endregion
/// <summary> #region Private Members
/// Processes the input Windows Message, routing the buffer to the correct Keyboard, Mouse or HID.
/// </summary> #region ConstructMessageWindow
/// <param name="msg">The WM_INPUT message, containing the buffer on the input event.</param>
protected override void WndProc(ref Message msg) static INativeWindow ConstructMessageWindow()
{ {
switch ((WindowMessage)msg.Msg) Debug.WriteLine("Initializing windows raw input driver.");
{ Debug.Indent();
case WindowMessage.INPUT:
int size = 0;
// Get the size of the input buffer
Functions.GetRawInputData(msg.LParam, GetRawInputDataEnum.INPUT,
IntPtr.Zero, ref size, API.RawInputHeaderSize);
//if (buffer == null || API.RawInputSize < size) // Create a new message-only window to retrieve WM_INPUT messages.
//{ Native = new NativeWindow();
// throw new ApplicationException("Critical error when processing raw windows input."); Native.ProcessEvents();
//} Functions.SetParent(Parent.WindowHandle, Constants.MESSAGE_ONLY);
if (size == Functions.GetRawInputData(msg.LParam, GetRawInputDataEnum.INPUT, Native.ProcessEvents();
out data, ref size, API.RawInputHeaderSize))
{
switch (data.Header.Type)
{
case RawInputDeviceType.KEYBOARD:
if (!keyboardDriver.ProcessKeyboardEvent(data))
Functions.DefRawInputProc(ref data, 1, (uint)API.RawInputHeaderSize);
return;
case RawInputDeviceType.MOUSE: // Subclass the window to retrieve the events we are interested in.
throw new NotSupportedException(); OldWndProc = Functions.SetWindowLong(Parent.WindowHandle, WndProc);
case RawInputDeviceType.HID: Debug.Print("Input window attached to parent {0}", Parent);
Functions.DefRawInputProc(ref data, 1, (uint)API.RawInputHeaderSize); keyboardDriver = new WinRawKeyboard(Parent.WindowHandle);
return; mouseDriver = new WinRawMouse(Parent.WindowHandle);
default: Debug.Unindent();
break; return Native;
}
}
else
{
throw new ApplicationException(String.Format(
"GetRawInputData returned invalid buffer. Windows error {0}. Please file a bug at http://opentk.sourceforge.net",
Marshal.GetLastWin32Error()));
}
break;
case WindowMessage.DESTROY:
Debug.Print("Input window detached from parent {0}.", Handle);
ReleaseHandle();
break;
case WindowMessage.QUIT:
Debug.WriteLine("Input window quit.");
this.Dispose();
break;
}
base.WndProc(ref msg);
} }
#endregion #endregion
#region --- IInputDriver Members --- #region WindowProcedureImplementation
// Processes the input Windows Message, routing the buffer to the correct Keyboard, Mouse or HID.
static IntPtr WindowProcedureImplementation(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
{
switch (message)
{
case WindowMessage.INPUT:
int size = 0;
// Get the size of the input buffer
Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
IntPtr.Zero, ref size, API.RawInputHeaderSize);
// Read the actual raw input structure
if (size == Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
out data, ref size, API.RawInputHeaderSize))
{
switch (data.Header.Type)
{
case RawInputDeviceType.KEYBOARD:
if (keyboardDriver.ProcessKeyboardEvent(data))
return IntPtr.Zero;
break;
case RawInputDeviceType.MOUSE:
if (mouseDriver.ProcessMouseEvent(data))
return IntPtr.Zero;
break;
case RawInputDeviceType.HID:
break;
}
}
break;
}
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
}
#endregion
#region ProcessEvents
static void ProcessEvents()
{
INativeWindow native = ConstructMessageWindow();
MSG msg = new MSG();
while (native.Exists)
{
int ret = Functions.GetMessage(ref msg, Parent.WindowHandle, 0, 0);
if (ret == -1)
{
throw new PlatformException(String.Format(
"An error happened while processing the message queue. Windows error: {0}",
Marshal.GetLastWin32Error()));
}
Functions.TranslateMessage(ref msg);
Functions.DispatchMessage(ref msg);
}
}
#endregion
#endregion
#region IInputDriver Members
#region IInputDriver Members #region IInputDriver Members
@ -203,7 +257,7 @@ namespace OpenTK.Platform.Windows
public IList<KeyboardDevice> Keyboard public IList<KeyboardDevice> Keyboard
{ {
get { return keyboardDriver.Keyboard; } get { return KeyboardDriver.Keyboard; }
} }
public KeyboardState GetState() public KeyboardState GetState()
@ -222,7 +276,7 @@ namespace OpenTK.Platform.Windows
public IList<MouseDevice> Mouse public IList<MouseDevice> Mouse
{ {
get { return mouseDriver.Mouse; } get { return MouseDriver.Mouse; }
} }
MouseState IMouseDriver.GetState() MouseState IMouseDriver.GetState()
@ -248,7 +302,26 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region --- IDisposable Members --- #region IInputDriver2 Members
public IMouseDriver MouseDriver
{
get { return mouseDriver; }
}
public IKeyboardDriver KeyboardDriver
{
get { return keyboardDriver; }
}
public IJoystickDriver JoystickDriver
{
get { return joystickDriver; }
}
#endregion
#region IDisposable Members
private bool disposed; private bool disposed;
@ -265,7 +338,7 @@ namespace OpenTK.Platform.Windows
if (manual) if (manual)
{ {
keyboardDriver.Dispose(); keyboardDriver.Dispose();
this.ReleaseHandle(); //mouseDriver.Dispose();
} }
disposed = true; disposed = true;
@ -274,6 +347,7 @@ namespace OpenTK.Platform.Windows
~WinRawInput() ~WinRawInput()
{ {
Debug.Print("[Warning] Resource leaked: {0}.", this);
Dispose(false); Dispose(false);
} }

View file

@ -1,7 +1,28 @@
#region --- License --- #region License
/* Copyright (c) 2007 Stefanos Apostolopoulos //
* See license.txt for license info // The Open Toolkit Library License
*/ //
// Copyright (c) 2006 - 2010 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion #endregion
#region --- Using directives --- #region --- Using directives ---

View file

@ -1,7 +1,28 @@
#region --- License --- #region License
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos //
* See license.txt for license info // The Open Toolkit Library License
*/ //
// Copyright (c) 2006 - 2010 the Open Toolkit library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion #endregion
using System; using System;
@ -22,25 +43,17 @@ namespace OpenTK.Platform.Windows
{ {
List<MouseState> mice; List<MouseState> mice;
Dictionary<ContextHandle, int> rawids; // ContextHandle instead of IntPtr for fast dictionary access Dictionary<ContextHandle, int> rawids; // ContextHandle instead of IntPtr for fast dictionary access
readonly INativeWindow native; readonly IntPtr Window;
readonly IntPtr window;
readonly WindowProcedure WndProc;
readonly IntPtr OldWndProc;
internal WinRawMouse() public WinRawMouse(IntPtr window)
{ {
Debug.WriteLine("Initializing mouse driver (WinRawMouse)."); Debug.WriteLine("Initializing mouse driver (WinRawMouse).");
Debug.Indent(); Debug.Indent();
// Create a new message-only window to retrieve WM_INPUT messages. if (window == IntPtr.Zero)
native = new NativeWindow(); throw new ArgumentNullException("window");
window = (native.WindowInfo as WinWindowInfo).WindowHandle;
//Functions.SetParent(window, Constants.MESSAGE_ONLY);
// Subclass the window to retrieve the events we are interested in.
WndProc = WindowProcedure;
OldWndProc = Functions.SetWindowLong(window, WndProc);
native.ProcessEvents();
Window = window;
RegisterDevices(window, out mice, out rawids); RegisterDevices(window, out mice, out rawids);
Debug.Unindent(); Debug.Unindent();
@ -52,7 +65,6 @@ namespace OpenTK.Platform.Windows
public MouseState GetState() public MouseState GetState()
{ {
native.ProcessEvents();
if (mice.Count > 0) if (mice.Count > 0)
return mice[0]; return mice[0];
else else
@ -61,7 +73,6 @@ namespace OpenTK.Platform.Windows
public MouseState GetState(int index) public MouseState GetState(int index)
{ {
native.ProcessEvents();
if (index < mice.Count) if (index < mice.Count)
return mice[index]; return mice[index];
else else
@ -172,49 +183,14 @@ namespace OpenTK.Platform.Windows
return state; return state;
} }
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam) public bool ProcessMouseEvent(RawInput rin)
{
switch (message)
{
case WindowMessage.INPUT:
int expected_size = 0, real_size = 0;
RawInput data = new RawInput();
// Get the size of the input buffer
Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
IntPtr.Zero, ref expected_size, API.RawInputHeaderSize);
// Read the actual data
unsafe
{
real_size = Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
&data, ref expected_size, API.RawInputHeaderSize);
}
if (real_size == expected_size)
{
if (data.Header.Type == RawInputDeviceType.MOUSE)
{
if (ProcessEvent(data.Header.Device, data.Data.Mouse))
{
return IntPtr.Zero;
}
}
}
// We didn't handle this message after all, give it back to the old WndProc.
goto default;
default:
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
}
}
bool ProcessEvent(IntPtr device, RawMouse raw)
{ {
if (mice.Count == 0) if (mice.Count == 0)
return false; return false;
ContextHandle handle = new ContextHandle(device); RawMouse raw = rin.Data.Mouse;
ContextHandle handle = new ContextHandle(rin.Header.Device);
MouseState mouse; MouseState mouse;
if (rawids.ContainsKey(handle)) if (rawids.ContainsKey(handle))
mouse = mice[rawids[handle]]; mouse = mice[rawids[handle]];
@ -249,7 +225,5 @@ namespace OpenTK.Platform.Windows
mice[rawids[handle]] = mouse; mice[rawids[handle]] = mouse;
return true; return true;
} }
} }
} }