Decoupled new driver API from old public interface.
WinRawMouse can now detect mouse disconnection/connection events.
This commit is contained in:
parent
2ea1b56b9d
commit
2934c9d004
26 changed files with 289 additions and 415 deletions
|
@ -253,7 +253,6 @@ namespace OpenTK
|
|||
|
||||
//event EventHandler<KeyEventArgs> KeyDown;
|
||||
//event EventHandler<KeyEventArgs> KeyUp;
|
||||
|
||||
|
||||
//event EventHandler<DragEventArgs> DragDrop;
|
||||
//event EventHandler<DragEventArgs> DragEnter;
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace OpenTK.Input
|
|||
// Defines the interface for a 2nd generation input driver.
|
||||
interface IInputDriver2
|
||||
{
|
||||
IMouseDriver MouseDriver { get; }
|
||||
IKeyboardDriver KeyboardDriver { get; }
|
||||
IJoystickDriver JoystickDriver { get; }
|
||||
IMouseDriver2 MouseDriver { get; }
|
||||
IKeyboardDriver2 KeyboardDriver { get; }
|
||||
IGamePadDriver GamePadDriver { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace OpenTK.Input
|
|||
/// <summary>
|
||||
/// Defines the interface for JoystickDevice drivers.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public interface IJoystickDriver
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
@ -13,24 +13,12 @@ namespace OpenTK.Input
|
|||
/// <summary>
|
||||
/// Defines the interface for KeyboardDevice drivers.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public interface IKeyboardDriver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the list of available KeyboardDevices.
|
||||
/// </summary>
|
||||
IList<KeyboardDevice> Keyboard { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the KeyboardState for the default keyboard device.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="OpenTK.Input.KeyboardState"/> structure containing the state of the keyboard device.</returns>
|
||||
KeyboardState GetState();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the KeyboardState for the specified keyboard device.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the keyboard device.</param>
|
||||
/// <returns>A <see cref="OpenTK.Input.KeyboardState"/> structure containing the state of the keyboard device.</returns>
|
||||
KeyboardState GetState(int index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,24 +13,12 @@ namespace OpenTK.Input
|
|||
/// <summary>
|
||||
/// Defines the interface for MouseDevice drivers.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
public interface IMouseDriver
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the list of available MouseDevices.
|
||||
/// </summary>
|
||||
IList<MouseDevice> Mouse { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the MouseState for the default keyboard device.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure containing the state of the mouse device.</returns>
|
||||
MouseState GetState();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the MouseState for the specified keyboard device.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the keyboard device.</param>
|
||||
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure containing the state of the mouse device.</returns>
|
||||
MouseState GetState(int index);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace OpenTK.Input
|
|||
{
|
||||
#region Fields
|
||||
|
||||
static readonly IKeyboardDriver driver =
|
||||
static readonly IKeyboardDriver2 driver =
|
||||
Platform.Factory.Default.CreateKeyboardDriver();
|
||||
static readonly object SyncRoot = new object();
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace OpenTK.Input
|
|||
/// <summary>
|
||||
/// Retrieves the combined <see cref="OpenTK.Input.KeyboardState"/> for all keyboard devices.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="OpenTK.Input.KeyboardState"/> structure containing the combined state for all keyboard devices.</returns>
|
||||
/// <returns>An <see cref="OpenTK.Input.KeyboardState"/> structure containing the combined state for all keyboard devices.</returns>
|
||||
public static KeyboardState GetState()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
|
@ -62,7 +62,7 @@ namespace OpenTK.Input
|
|||
/// Retrieves the <see cref="OpenTK.Input.KeyboardState"/> for the specified keyboard device.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the keyboard device.</param>
|
||||
/// <returns>A <see cref="OpenTK.Input.KeyboardState"/> structure containing the state of the keyboard device.</returns>
|
||||
/// <returns>An <see cref="OpenTK.Input.KeyboardState"/> structure containing the state of the keyboard device.</returns>
|
||||
public static KeyboardState GetState(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
|
@ -75,5 +75,23 @@ namespace OpenTK.Input
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the device name for the keyboard device.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the keyboard device.</param>
|
||||
/// <returns>A <see cref="System.String"/> with the name of the specified device or <see cref="System.String.Empty"/>.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If no device exists at the specified index, the return value is <see cref="System.String.Empty"/>.</para></remarks>
|
||||
public static string GetDeviceName(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
|
||||
lock (SyncRoot)
|
||||
{
|
||||
return driver.GetDeviceName(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace OpenTK.Input
|
|||
{
|
||||
#region Fields
|
||||
|
||||
static readonly IMouseDriver driver =
|
||||
static readonly IMouseDriver2 driver =
|
||||
Platform.Factory.Default.CreateMouseDriver();
|
||||
static readonly object SyncRoot = new object();
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace OpenTK.Input
|
|||
unsafe fixed int Buttons[NumInts];
|
||||
int x, y;
|
||||
float wheel;
|
||||
bool is_connected;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -179,6 +180,12 @@ namespace OpenTK.Input
|
|||
get { return Wheel; }
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get { return is_connected; }
|
||||
internal set { is_connected = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether two <see cref="MouseState" /> instances are equal.
|
||||
/// </summary>
|
||||
|
@ -314,6 +321,7 @@ namespace OpenTK.Input
|
|||
WheelPrecise += other.WheelPrecise;
|
||||
X += other.X;
|
||||
Y += other.Y;
|
||||
IsConnected |= other.IsConnected;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,10 @@
|
|||
<Compile Include="DisplayDevice.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Input\IGamePadDriver.cs" />
|
||||
<Compile Include="Input\IInputDriver2.cs" />
|
||||
<Compile Include="Input\IKeyboardDriver2.cs" />
|
||||
<Compile Include="Input\IMouseDriver2.cs" />
|
||||
<Compile Include="WindowBorder.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -114,12 +114,12 @@ namespace OpenTK.Platform
|
|||
return default_implementation.CreateGraphicsMode();
|
||||
}
|
||||
|
||||
public OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
|
||||
public OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return default_implementation.CreateKeyboardDriver();
|
||||
}
|
||||
|
||||
public OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||
public OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
return default_implementation.CreateMouseDriver();
|
||||
}
|
||||
|
@ -169,12 +169,12 @@ namespace OpenTK.Platform
|
|||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
||||
public OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
|
||||
public OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
||||
public OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||
public OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace OpenTK.Platform
|
|||
|
||||
IGraphicsMode CreateGraphicsMode();
|
||||
|
||||
OpenTK.Input.IKeyboardDriver CreateKeyboardDriver();
|
||||
OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver();
|
||||
|
||||
OpenTK.Input.IMouseDriver CreateMouseDriver();
|
||||
OpenTK.Input.IMouseDriver2 CreateMouseDriver();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace OpenTK.Platform.MacOS
|
|||
{
|
||||
using Input;
|
||||
|
||||
class CarbonInput : IInputDriver
|
||||
class CarbonInput : IInputDriver, IInputDriver2
|
||||
{
|
||||
List<KeyboardDevice> dummy_keyboard_list = new List<KeyboardDevice>(1);
|
||||
List<MouseDevice> dummy_mice_list = new List<MouseDevice>(1);
|
||||
|
@ -35,16 +35,6 @@ namespace OpenTK.Platform.MacOS
|
|||
get { return dummy_keyboard_list; }
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMouseDriver Members
|
||||
|
@ -54,16 +44,6 @@ namespace OpenTK.Platform.MacOS
|
|||
get { return dummy_mice_list; }
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IJoystickDriver Members
|
||||
|
@ -82,5 +62,20 @@ namespace OpenTK.Platform.MacOS
|
|||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public IMouseDriver2 MouseDriver
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public IKeyboardDriver2 KeyboardDriver
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public IGamePadDriver GamePadDriver
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,12 +70,12 @@ namespace OpenTK.Platform.MacOS
|
|||
return new MacOSGraphicsMode();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace OpenTK.Platform.Windows
|
|||
using RECT = OpenTK.Platform.Windows.Win32Rectangle;
|
||||
using WNDPROC = System.IntPtr;
|
||||
using LPDEVMODE = DeviceMode;
|
||||
using HDEVNOTIFY = System.IntPtr;
|
||||
|
||||
using HRESULT = System.IntPtr;
|
||||
using HMONITOR = System.IntPtr;
|
||||
|
@ -845,7 +846,7 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
[DllImport("user32.dll", SetLastError=true)]
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern BOOL SetForegroundWindow(HWND hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -854,6 +855,13 @@ namespace OpenTK.Platform.Windows
|
|||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern BOOL SetParent(HWND child, HWND newParent);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern HDEVNOTIFY RegisterDeviceNotification(HANDLE hRecipient,
|
||||
LPVOID NotificationFilter, DeviceNotification Flags);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern BOOL UnregisterDeviceNotification(HDEVNOTIFY Handle);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Display settings
|
||||
|
@ -2794,6 +2802,30 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region BroadcastHeader
|
||||
|
||||
struct BroadcastHeader
|
||||
{
|
||||
public DWORD Size;
|
||||
public DeviceBroadcastType DeviceType;
|
||||
DWORD dbch_reserved;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region BroadcastDeviceInterface
|
||||
|
||||
struct BroadcastDeviceInterface
|
||||
{
|
||||
public DWORD Size;
|
||||
public DeviceBroadcastType DeviceType;
|
||||
DWORD dbcc_reserved;
|
||||
public Guid ClassGuid;
|
||||
public char dbcc_name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Enums ---
|
||||
|
@ -4130,6 +4162,30 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region DeviceNotification
|
||||
|
||||
enum DeviceNotification
|
||||
{
|
||||
WINDOW_HANDLE = 0x00000000,
|
||||
SERVICE_HANDLE = 0x00000001,
|
||||
ALL_INTERFACE_CLASSES = 0x00000004,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DeviceBroadcastType
|
||||
|
||||
enum DeviceBroadcastType
|
||||
{
|
||||
OEM = 0,
|
||||
VOLUME = 2,
|
||||
PORT = 3,
|
||||
INTERFACE = 5,
|
||||
HANDLE = 6,
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- Callbacks ---
|
||||
|
@ -4190,4 +4246,4 @@ namespace OpenTK.Platform.Windows
|
|||
#pragma warning restore 3019
|
||||
#pragma warning restore 0649
|
||||
#pragma warning restore 0169
|
||||
#pragma warning restore 0414
|
||||
#pragma warning restore 0414
|
||||
|
|
|
@ -37,11 +37,11 @@ using System.Drawing;
|
|||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
// Input driver for legacy (pre XP) Windows platforms.
|
||||
sealed class WMInput : System.Windows.Forms.NativeWindow, IInputDriver, IInputDriver2
|
||||
sealed class WMInput : System.Windows.Forms.NativeWindow, IInputDriver2
|
||||
{
|
||||
#region --- Fields ---
|
||||
|
||||
WinMMJoystick joystick_driver = new WinMMJoystick();
|
||||
WinMMJoystick gamepad_driver = new WinMMJoystick();
|
||||
// Driver supports only one keyboard and mouse;
|
||||
KeyboardDevice keyboard = new KeyboardDevice();
|
||||
MouseDevice mouse = new MouseDevice();
|
||||
|
@ -249,66 +249,6 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region --- IInputDriver Members ---
|
||||
|
||||
#region IInputDriver Members
|
||||
|
||||
public void Poll()
|
||||
{
|
||||
joystick_driver.Poll();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IKeyboardDriver Members
|
||||
|
||||
public IList<KeyboardDevice> Keyboard
|
||||
{
|
||||
get { return keyboards; }
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMouseDriver Members
|
||||
|
||||
public IList<MouseDevice> Mouse
|
||||
{
|
||||
get { return mice; }
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IJoystickDriver Members
|
||||
|
||||
public IList<JoystickDevice> Joysticks
|
||||
{
|
||||
get { return joystick_driver.Joysticks; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- IDisposable Members ---
|
||||
|
||||
private bool disposed;
|
||||
|
@ -337,19 +277,19 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
public IMouseDriver MouseDriver
|
||||
public IMouseDriver2 MouseDriver
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public IKeyboardDriver KeyboardDriver
|
||||
public IKeyboardDriver2 KeyboardDriver
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public IJoystickDriver JoystickDriver
|
||||
public IGamePadDriver GamePadDriver
|
||||
{
|
||||
get { return joystick_driver; }
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -74,12 +74,12 @@ namespace OpenTK.Platform.Windows
|
|||
return new WinGraphicsMode();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return InputDriver.KeyboardDriver;
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
return InputDriver.MouseDriver;
|
||||
}
|
||||
|
|
|
@ -1227,16 +1227,6 @@ namespace OpenTK.Platform.Windows
|
|||
get { return mice; }
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IJoystickDriver Members
|
||||
|
|
|
@ -36,7 +36,7 @@ using System.Diagnostics;
|
|||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
sealed class WinMMJoystick : IJoystickDriver
|
||||
sealed class WinMMJoystick : IJoystickDriver, IGamePadDriver
|
||||
{
|
||||
#region Fields
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ using System.Threading;
|
|||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
// Not complete.
|
||||
sealed class WinRawInput : IInputDriver, IInputDriver2
|
||||
sealed class WinRawInput : IInputDriver2
|
||||
{
|
||||
// Input event data.
|
||||
static RawInput data = new RawInput();
|
||||
|
@ -56,6 +56,9 @@ namespace OpenTK.Platform.Windows
|
|||
static WinWindowInfo Parent { get { return Native.WindowInfo as WinWindowInfo; } }
|
||||
static readonly WindowProcedure WndProc = WindowProcedureImplementation;
|
||||
static IntPtr OldWndProc;
|
||||
|
||||
static IntPtr DevNotifyHandle;
|
||||
static readonly Guid DeviceInterfaceHid = new Guid("4D1E55B2-F16F-11CF-88CB-001111000030");
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
@ -102,6 +105,7 @@ namespace OpenTK.Platform.Windows
|
|||
Native.ProcessEvents();
|
||||
Functions.SetParent(Parent.WindowHandle, Constants.MESSAGE_ONLY);
|
||||
Native.ProcessEvents();
|
||||
RegisterForDeviceNotifications();
|
||||
|
||||
// Subclass the window to retrieve the events we are interested in.
|
||||
OldWndProc = Functions.SetWindowLong(Parent.WindowHandle, WndProc);
|
||||
|
@ -114,6 +118,21 @@ namespace OpenTK.Platform.Windows
|
|||
return Native;
|
||||
}
|
||||
|
||||
static void RegisterForDeviceNotifications()
|
||||
{
|
||||
BroadcastDeviceInterface bdi = new BroadcastDeviceInterface();
|
||||
bdi.Size = BlittableValueType.StrideOf(bdi);
|
||||
bdi.DeviceType = DeviceBroadcastType.INTERFACE;
|
||||
bdi.ClassGuid = DeviceInterfaceHid;
|
||||
unsafe
|
||||
{
|
||||
DevNotifyHandle = Functions.RegisterDeviceNotification(Parent.WindowHandle,
|
||||
new IntPtr((void*)&bdi), DeviceNotification.WINDOW_HANDLE);
|
||||
}
|
||||
if (DevNotifyHandle == IntPtr.Zero)
|
||||
Debug.Print("[Warning] Failed to register for device notifications. Error: {0}", Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowProcedureImplementation
|
||||
|
@ -150,6 +169,10 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WindowMessage.DEVICECHANGE:
|
||||
mouseDriver.RefreshDevices();
|
||||
break;
|
||||
}
|
||||
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
|
||||
}
|
||||
|
@ -182,139 +205,19 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region IInputDriver Members
|
||||
|
||||
#region IInputDriver Members
|
||||
|
||||
public void Poll()
|
||||
{
|
||||
return;
|
||||
#if false
|
||||
// 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.
|
||||
int size = 0;
|
||||
Functions.GetRawInputBuffer(IntPtr.Zero, ref size, API.RawInputHeaderSize);
|
||||
size *= 256;
|
||||
IntPtr rin_data = Marshal.AllocHGlobal(size);
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Iterate reading all available RawInput structures and routing them to their respective
|
||||
// handlers.
|
||||
int num = Functions.GetRawInputBuffer(rin_data, ref size, API.RawInputHeaderSize);
|
||||
if (num == 0)
|
||||
break;
|
||||
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();
|
||||
break;
|
||||
}
|
||||
|
||||
RawInput[] rin_structs = new RawInput[num];
|
||||
IntPtr next_rin = rin_data;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
rin_structs[i] = (RawInput)Marshal.PtrToStructure(next_rin, typeof(RawInput));
|
||||
|
||||
switch (rin_structs[i].Header.Type)
|
||||
{
|
||||
case RawInputDeviceType.KEYBOARD:
|
||||
keyboardDriver.ProcessKeyboardEvent(rin_structs[i]);
|
||||
break;
|
||||
|
||||
case RawInputDeviceType.MOUSE:
|
||||
mouseDriver.ProcessEvent(rin_structs[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
next_rin = Functions.NextRawInputStructure(next_rin);
|
||||
}
|
||||
Functions.DefRawInputProc(rin_structs, num, (uint)API.RawInputHeaderSize);
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(rin_data);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IKeyboardDriver Members
|
||||
|
||||
public IList<KeyboardDevice> Keyboard
|
||||
{
|
||||
get { return KeyboardDriver.Keyboard; }
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMouseDriver Members
|
||||
|
||||
public IList<MouseDevice> Mouse
|
||||
{
|
||||
get { return MouseDriver.Mouse; }
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IJoystickDriver Members
|
||||
|
||||
public IList<JoystickDevice> Joysticks
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region IInputDriver2 Members
|
||||
|
||||
public IMouseDriver MouseDriver
|
||||
public IMouseDriver2 MouseDriver
|
||||
{
|
||||
get { return mouseDriver; }
|
||||
}
|
||||
|
||||
public IKeyboardDriver KeyboardDriver
|
||||
public IKeyboardDriver2 KeyboardDriver
|
||||
{
|
||||
get { return keyboardDriver; }
|
||||
}
|
||||
|
||||
public IJoystickDriver JoystickDriver
|
||||
public IGamePadDriver GamePadDriver
|
||||
{
|
||||
get { return joystickDriver; }
|
||||
}
|
||||
|
@ -337,10 +240,9 @@ namespace OpenTK.Platform.Windows
|
|||
{
|
||||
if (manual)
|
||||
{
|
||||
keyboardDriver.Dispose();
|
||||
//mouseDriver.Dispose();
|
||||
}
|
||||
|
||||
Functions.UnregisterDeviceNotification(DevNotifyHandle);
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,10 @@ using OpenTK.Input;
|
|||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal class WinRawKeyboard : IKeyboardDriver, IDisposable
|
||||
internal class WinRawKeyboard : IKeyboardDriver2
|
||||
{
|
||||
readonly List<KeyboardState> keyboards = new List<KeyboardState>();
|
||||
readonly List<string> names = new List<string>();
|
||||
// ContextHandle instead of IntPtr for fast dictionary access
|
||||
readonly Dictionary<ContextHandle, int> rawids = new Dictionary<ContextHandle, int>();
|
||||
private List<KeyboardDevice> keyboards_old = new List<KeyboardDevice>();
|
||||
|
@ -142,6 +143,7 @@ namespace OpenTK.Platform.Windows
|
|||
//}
|
||||
|
||||
keyboards.Add(new KeyboardState());
|
||||
names.Add(deviceDesc);
|
||||
rawids.Add(new ContextHandle(ridl[i].Device), keyboards.Count - 1);
|
||||
}
|
||||
}
|
||||
|
@ -261,11 +263,6 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#region --- IKeyboardDriver Members ---
|
||||
|
||||
public IList<KeyboardDevice> Keyboard
|
||||
{
|
||||
get { return keyboards_old; }
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
|
@ -290,35 +287,17 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- IDisposable Members ---
|
||||
|
||||
private bool disposed;
|
||||
|
||||
public void Dispose()
|
||||
public string GetDeviceName(int index)
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
lock (UpdateLock)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
keyboards_old.Clear();
|
||||
}
|
||||
disposed = true;
|
||||
if (names.Count > index)
|
||||
return names[index];
|
||||
else
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
~WinRawKeyboard()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,11 @@ namespace OpenTK.Platform.Windows
|
|||
/// <summary>
|
||||
/// Contains methods to register for and process mouse WM_INPUT messages.
|
||||
/// </summary>
|
||||
internal class WinRawMouse : IMouseDriver
|
||||
internal class WinRawMouse : IMouseDriver2
|
||||
{
|
||||
List<MouseState> mice;
|
||||
Dictionary<ContextHandle, int> rawids; // ContextHandle instead of IntPtr for fast dictionary access
|
||||
readonly List<MouseState> mice = new List<MouseState>();
|
||||
readonly List<string> names = new List<string>();
|
||||
readonly Dictionary<ContextHandle, int> rawids = new Dictionary<ContextHandle, int>();
|
||||
readonly IntPtr Window;
|
||||
readonly object UpdateLock = new object();
|
||||
|
||||
|
@ -55,15 +56,13 @@ namespace OpenTK.Platform.Windows
|
|||
throw new ArgumentNullException("window");
|
||||
|
||||
Window = window;
|
||||
RegisterDevices(window, out mice, out rawids);
|
||||
RefreshDevices();
|
||||
|
||||
Debug.Unindent();
|
||||
}
|
||||
|
||||
#region IMouseDriver Members
|
||||
|
||||
public IList<MouseDevice> Mouse { get { throw new NotImplementedException(); } }
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
|
@ -90,77 +89,114 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
static int RegisterDevices(IntPtr window, out List<MouseState> mice, out Dictionary<ContextHandle, int> rawids)
|
||||
public void RefreshDevices()
|
||||
{
|
||||
int count = WinRawInput.DeviceCount;
|
||||
mice = new List<MouseState>();
|
||||
rawids = new Dictionary<ContextHandle, int>();
|
||||
|
||||
RawInputDeviceList[] ridl = new RawInputDeviceList[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
ridl[i] = new RawInputDeviceList();
|
||||
Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize);
|
||||
|
||||
// Discover mouse devices:
|
||||
for (int i = 0; i < count; i++)
|
||||
lock (UpdateLock)
|
||||
{
|
||||
uint size = 0;
|
||||
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICENAME, IntPtr.Zero, ref size);
|
||||
IntPtr name_ptr = Marshal.AllocHGlobal((IntPtr)size);
|
||||
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICENAME, name_ptr, ref size);
|
||||
string name = Marshal.PtrToStringAnsi(name_ptr);
|
||||
Marshal.FreeHGlobal(name_ptr);
|
||||
|
||||
if (name.ToLower().Contains("root"))
|
||||
// Mark all devices as disconnected. We will check which of those
|
||||
// are connected later on.
|
||||
for (int i = 0; i < mice.Count; i++)
|
||||
{
|
||||
// This is a terminal services device, skip it.
|
||||
continue;
|
||||
MouseState state = mice[i];
|
||||
state.IsConnected = false;
|
||||
mice[i] = state;
|
||||
}
|
||||
else if (ridl[i].Type == RawInputDeviceType.MOUSE || ridl[i].Type == RawInputDeviceType.HID)
|
||||
|
||||
int count = WinRawInput.DeviceCount;
|
||||
RawInputDeviceList[] ridl = new RawInputDeviceList[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
ridl[i] = new RawInputDeviceList();
|
||||
Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize);
|
||||
|
||||
// Discover mouse devices
|
||||
foreach (RawInputDeviceList dev in ridl)
|
||||
{
|
||||
// This is a mouse or a USB mouse device. In the latter case, discover if it really is a
|
||||
// mouse device by qeurying the registry.
|
||||
|
||||
// remove the \??\
|
||||
name = name.Substring(4);
|
||||
|
||||
string[] split = name.Split('#');
|
||||
|
||||
string id_01 = split[0]; // ACPI (Class code)
|
||||
string id_02 = split[1]; // PNP0303 (SubClass code)
|
||||
string id_03 = split[2]; // 3&13c0b0c5&0 (Protocol code)
|
||||
// The final part is the class GUID and is not needed here
|
||||
|
||||
string findme = string.Format(
|
||||
@"System\CurrentControlSet\Enum\{0}\{1}\{2}",
|
||||
id_01, id_02, id_03);
|
||||
|
||||
RegistryKey regkey = Registry.LocalMachine.OpenSubKey(findme);
|
||||
|
||||
string deviceDesc = (string)regkey.GetValue("DeviceDesc");
|
||||
deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
|
||||
string deviceClass = (string)regkey.GetValue("Class");
|
||||
|
||||
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
|
||||
ContextHandle id = new ContextHandle(dev.Device);
|
||||
if (rawids.ContainsKey(id))
|
||||
{
|
||||
// Register the device:
|
||||
RawInputDeviceInfo info = new RawInputDeviceInfo();
|
||||
int devInfoSize = API.RawInputDeviceInfoSize;
|
||||
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||
info, ref devInfoSize);
|
||||
// Device already registered, mark as connected
|
||||
MouseState state = mice[rawids[id]];
|
||||
state.IsConnected = true;
|
||||
mice[rawids[id]] = state;
|
||||
continue;
|
||||
}
|
||||
|
||||
mice.Add(RegisterRawDevice(deviceDesc, window));
|
||||
rawids.Add(new ContextHandle(ridl[i].Device), mice.Count - 1);
|
||||
// Unregistered device, find what it is
|
||||
string name = GetDeviceName(dev);
|
||||
if (name.ToLower().Contains("root"))
|
||||
{
|
||||
// This is a terminal services device, skip it.
|
||||
continue;
|
||||
}
|
||||
else if (dev.Type == RawInputDeviceType.MOUSE || dev.Type == RawInputDeviceType.HID)
|
||||
{
|
||||
// This is a mouse or a USB mouse device. In the latter case, discover if it really is a
|
||||
// mouse device by qeurying the registry.
|
||||
RegistryKey regkey = FindRegistryKey(name);
|
||||
string deviceDesc = (string)regkey.GetValue("DeviceDesc");
|
||||
deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
|
||||
string deviceClass = (string)regkey.GetValue("Class");
|
||||
|
||||
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
|
||||
{
|
||||
if (!rawids.ContainsKey(new ContextHandle(dev.Device)))
|
||||
{
|
||||
// Register the device:
|
||||
RawInputDeviceInfo info = new RawInputDeviceInfo();
|
||||
int devInfoSize = API.RawInputDeviceInfoSize;
|
||||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||
info, ref devInfoSize);
|
||||
|
||||
RegisterRawDevice(deviceDesc, Window);
|
||||
MouseState state = new MouseState();
|
||||
state.IsConnected = true;
|
||||
mice.Add(state);
|
||||
names.Add(deviceDesc);
|
||||
rawids.Add(new ContextHandle(dev.Device), mice.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static MouseState RegisterRawDevice(string device, IntPtr window)
|
||||
static string GetDeviceName(RawInputDeviceList dev)
|
||||
{
|
||||
// get name size
|
||||
uint size = 0;
|
||||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICENAME, IntPtr.Zero, ref size);
|
||||
|
||||
// get actual name
|
||||
IntPtr name_ptr = Marshal.AllocHGlobal((IntPtr)size);
|
||||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICENAME, name_ptr, ref size);
|
||||
string name = Marshal.PtrToStringAnsi(name_ptr);
|
||||
Marshal.FreeHGlobal(name_ptr);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static RegistryKey FindRegistryKey(string name)
|
||||
{
|
||||
// remove the \??\
|
||||
name = name.Substring(4);
|
||||
|
||||
string[] split = name.Split('#');
|
||||
|
||||
string id_01 = split[0]; // ACPI (Class code)
|
||||
string id_02 = split[1]; // PNP0303 (SubClass code)
|
||||
string id_03 = split[2]; // 3&13c0b0c5&0 (Protocol code)
|
||||
// The final part is the class GUID and is not needed here
|
||||
|
||||
string findme = string.Format(
|
||||
@"System\CurrentControlSet\Enum\{0}\{1}\{2}",
|
||||
id_01, id_02, id_03);
|
||||
|
||||
RegistryKey regkey = Registry.LocalMachine.OpenSubKey(findme);
|
||||
return regkey;
|
||||
}
|
||||
|
||||
static void RegisterRawDevice(string device, IntPtr window)
|
||||
{
|
||||
MouseState state = new MouseState();
|
||||
RawInputDevice[] rid = new RawInputDevice[1];
|
||||
// Mouse is 1/2 (page/id). See http://www.microsoft.com/whdc/device/input/HID_HWID.mspx
|
||||
rid[0] = new RawInputDevice();
|
||||
|
@ -171,40 +207,24 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
if (!Functions.RegisterRawInputDevices(rid, 1, API.RawInputDeviceSize))
|
||||
{
|
||||
throw new ApplicationException(
|
||||
String.Format(
|
||||
"Raw input registration failed with error: {0}. Device: {1}",
|
||||
Marshal.GetLastWin32Error(),
|
||||
rid[0].ToString())
|
||||
);
|
||||
Debug.Print("[Warning] Raw input registration failed with error: {0}. Device: {1}",
|
||||
Marshal.GetLastWin32Error(), rid[0].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Registered mouse {0}", device);
|
||||
Point p = new Point();
|
||||
if (Functions.GetCursorPos(ref p))
|
||||
{
|
||||
state.X = p.X;
|
||||
state.Y = p.Y;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
public bool ProcessMouseEvent(RawInput rin)
|
||||
{
|
||||
if (mice.Count == 0)
|
||||
return false;
|
||||
|
||||
RawMouse raw = rin.Data.Mouse;
|
||||
ContextHandle handle = new ContextHandle(rin.Header.Device);
|
||||
|
||||
MouseState mouse;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
{
|
||||
mice.Add(new MouseState());
|
||||
rawids.Add(handle, mice.Count - 1);
|
||||
RefreshDevices();
|
||||
}
|
||||
mouse = mice[rawids[handle]];
|
||||
|
||||
|
|
|
@ -78,12 +78,12 @@ namespace OpenTK.Platform.X11
|
|||
return new X11GraphicsMode();
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IKeyboardDriver CreateKeyboardDriver()
|
||||
public virtual OpenTK.Input.IKeyboardDriver2 CreateKeyboardDriver()
|
||||
{
|
||||
return new X11Keyboard(null);
|
||||
}
|
||||
|
||||
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||
public virtual OpenTK.Input.IMouseDriver2 CreateMouseDriver()
|
||||
{
|
||||
if (XI2Mouse.IsSupported(IntPtr.Zero))
|
||||
return new XI2Mouse(null); // Requires xorg 1.7 or higher.
|
||||
|
|
|
@ -219,16 +219,6 @@ namespace OpenTK.Platform.X11
|
|||
get { return dummy_keyboard_list; }//return keyboardDriver.Keyboard;
|
||||
}
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public KeyboardState GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public IList<Mouse> Mouse
|
||||
|
@ -238,16 +228,6 @@ namespace OpenTK.Platform.X11
|
|||
get { return (IList<MouseDevice>)dummy_mice_list; } //return mouseDriver.Mouse;
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
MouseState IMouseDriver.GetState(int index)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region public IList<JoystickDevice> Joysticks
|
||||
|
|
|
@ -33,11 +33,13 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
// Standard keyboard driver that relies on xlib input events.
|
||||
// Only one keyboard supported.
|
||||
sealed class X11Keyboard : IKeyboardDriver
|
||||
sealed class X11Keyboard : IKeyboardDriver2
|
||||
{
|
||||
readonly X11WindowInfo window;
|
||||
readonly X11KeyMap keymap = new X11KeyMap();
|
||||
readonly static string name = "Core X11 keyboard";
|
||||
KeyboardState state = new KeyboardState();
|
||||
|
||||
|
||||
// Can either attach itself to the specified window or can hook the root window.
|
||||
public X11Keyboard(X11WindowInfo win)
|
||||
|
@ -64,9 +66,6 @@ namespace OpenTK.Platform.X11
|
|||
}
|
||||
}
|
||||
|
||||
// Todo: remove this
|
||||
public IList<KeyboardDevice> Keyboard { get { throw new NotSupportedException(); } }
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
ProcessEvents();
|
||||
|
@ -76,11 +75,19 @@ namespace OpenTK.Platform.X11
|
|||
public KeyboardState GetState(int index)
|
||||
{
|
||||
// X11Keyboard supports a single keyboard only
|
||||
if (index < 0 || index > 1)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
|
||||
ProcessEvents();
|
||||
return state;
|
||||
if (index == 0)
|
||||
return state;
|
||||
else
|
||||
return new KeyboardState();
|
||||
}
|
||||
|
||||
public string GetDeviceName(int index)
|
||||
{
|
||||
if (index == 0)
|
||||
return name;
|
||||
else
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
void ProcessEvents()
|
||||
|
|
|
@ -32,7 +32,7 @@ using OpenTK.Input;
|
|||
|
||||
namespace OpenTK.Platform.X11
|
||||
{
|
||||
sealed class X11Mouse : IMouseDriver
|
||||
sealed class X11Mouse : IMouseDriver2
|
||||
{
|
||||
MouseState mouse = new MouseState();
|
||||
X11WindowInfo window;
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
// Todo: multi-mouse support. Right now we aggregate all data into a single mouse device.
|
||||
// This should be easy: just read the device id and route the data to the correct device.
|
||||
sealed class XI2Mouse : IMouseDriver
|
||||
sealed class XI2Mouse : IMouseDriver2
|
||||
{
|
||||
List<MouseState> mice = new List<MouseState>();
|
||||
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
|
||||
|
|
Loading…
Reference in a new issue