mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-12 10:25:37 +00:00
Initial implementation of raw mouse input on Windows.
This commit is contained in:
parent
687594db4c
commit
ef6c910d30
|
@ -851,6 +851,9 @@ namespace OpenTK.Platform.Windows
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern BOOL BringWindowToTop(HWND hWnd);
|
public static extern BOOL BringWindowToTop(HWND hWnd);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
public static extern BOOL SetParent(HWND child, HWND newParent);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Display settings
|
#region Display settings
|
||||||
|
@ -1353,17 +1356,6 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// GetRawInputData gets the raw input one RawInput structure at a time. In contrast, GetRawInputBuffer gets an array of RawInput structures.
|
/// GetRawInputData gets the raw input one RawInput structure at a time. In contrast, GetRawInputBuffer gets an array of RawInput structures.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[CLSCompliant(false)]
|
|
||||||
[System.Security.SuppressUnmanagedCodeSecurity]
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
internal static extern UINT GetRawInputData(
|
|
||||||
HRAWINPUT RawInput,
|
|
||||||
GetRawInputDataEnum Command,
|
|
||||||
[Out] LPVOID Data,
|
|
||||||
[In, Out] ref UINT Size,
|
|
||||||
UINT SizeHeader
|
|
||||||
);
|
|
||||||
|
|
||||||
[System.Security.SuppressUnmanagedCodeSecurity]
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
internal static extern INT GetRawInputData(
|
internal static extern INT GetRawInputData(
|
||||||
|
@ -1395,17 +1387,6 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// GetRawInputData gets the raw input one RawInput structure at a time. In contrast, GetRawInputBuffer gets an array of RawInput structures.
|
/// GetRawInputData gets the raw input one RawInput structure at a time. In contrast, GetRawInputBuffer gets an array of RawInput structures.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[CLSCompliant(false)]
|
|
||||||
[System.Security.SuppressUnmanagedCodeSecurity]
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
|
||||||
internal static extern UINT GetRawInputData(
|
|
||||||
HRAWINPUT RawInput,
|
|
||||||
GetRawInputDataEnum Command,
|
|
||||||
/*[MarshalAs(UnmanagedType.LPStruct)]*/ [Out] out RawInput Data,
|
|
||||||
[In, Out] ref UINT Size,
|
|
||||||
UINT SizeHeader
|
|
||||||
);
|
|
||||||
|
|
||||||
[System.Security.SuppressUnmanagedCodeSecurity]
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
internal static extern INT GetRawInputData(
|
internal static extern INT GetRawInputData(
|
||||||
|
@ -1416,6 +1397,16 @@ namespace OpenTK.Platform.Windows
|
||||||
INT SizeHeader
|
INT SizeHeader
|
||||||
);
|
);
|
||||||
|
|
||||||
|
[System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
unsafe internal static extern INT GetRawInputData(
|
||||||
|
HRAWINPUT RawInput,
|
||||||
|
GetRawInputDataEnum Command,
|
||||||
|
RawInput* Data,
|
||||||
|
[In, Out] ref INT Size,
|
||||||
|
INT SizeHeader
|
||||||
|
);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IntPtr NextRawInputStructure(IntPtr data)
|
#region IntPtr NextRawInputStructure(IntPtr data)
|
||||||
|
@ -1487,7 +1478,7 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
#region --- Constants ---
|
#region --- Constants ---
|
||||||
|
|
||||||
internal struct Constants
|
static class Constants
|
||||||
{
|
{
|
||||||
// Found in winuser.h
|
// Found in winuser.h
|
||||||
internal const int KEYBOARD_OVERRUN_MAKE_CODE = 0xFF;
|
internal const int KEYBOARD_OVERRUN_MAKE_CODE = 0xFF;
|
||||||
|
@ -1574,6 +1565,8 @@ namespace OpenTK.Platform.Windows
|
||||||
// (found in winuser.h)
|
// (found in winuser.h)
|
||||||
internal const int ENUM_REGISTRY_SETTINGS = -2;
|
internal const int ENUM_REGISTRY_SETTINGS = -2;
|
||||||
internal const int ENUM_CURRENT_SETTINGS = -1;
|
internal const int ENUM_CURRENT_SETTINGS = -1;
|
||||||
|
|
||||||
|
internal static readonly IntPtr MESSAGE_ONLY = new IntPtr(-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -2231,25 +2224,11 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <para>To get device specific information, call GetRawInputDeviceInfo with the hDevice from RAWINPUTHEADER.</para>
|
/// <para>To get device specific information, call GetRawInputDeviceInfo with the hDevice from RAWINPUTHEADER.</para>
|
||||||
/// <para>Raw input is available only when the application calls RegisterRawInputDevices with valid device specifications.</para>
|
/// <para>Raw input is available only when the application calls RegisterRawInputDevices with valid device specifications.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
internal struct RawInput
|
struct RawInput
|
||||||
{
|
{
|
||||||
internal RawInputHeader Header;
|
public RawInputHeader Header;
|
||||||
internal RawInputData Data;
|
public RawInputData Data;
|
||||||
|
|
||||||
internal byte[] ToByteArray()
|
|
||||||
{
|
|
||||||
unsafe
|
|
||||||
{
|
|
||||||
byte[] dump = new byte[API.RawInputSize];
|
|
||||||
fixed (RawInputDeviceType* ptr = &Header.Type)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < API.RawInputSize; i++)
|
|
||||||
dump[i] = *((byte*)ptr + i);
|
|
||||||
return dump;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
@ -2350,38 +2329,9 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains information about the state of the mouse.
|
/// Contains information about the state of the mouse.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack=1)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
internal struct RawMouse
|
internal struct RawMouse
|
||||||
{
|
{
|
||||||
//internal RawMouseFlags Flags; // USHORT in winuser.h, but only INT works -- USHORT returns 0.
|
|
||||||
USHORT flags;
|
|
||||||
byte for_alignment; // Not used -- used for alignment
|
|
||||||
/// <summary>
|
|
||||||
/// Reserved.
|
|
||||||
/// </summary>
|
|
||||||
//ULONG Buttons;
|
|
||||||
internal USHORT buttonFlags;
|
|
||||||
/// <summary>
|
|
||||||
/// If usButtonFlags is RI_MOUSE_WHEEL, this member is a signed value that specifies the wheel delta.
|
|
||||||
/// </summary>
|
|
||||||
internal USHORT ButtonData;// { get { return (USHORT)((Buttons & 0xFFFF0000) >> 16); } }
|
|
||||||
/// <summary>
|
|
||||||
/// Raw state of the mouse buttons.
|
|
||||||
/// </summary>
|
|
||||||
internal ULONG RawButtons;
|
|
||||||
/// <summary>
|
|
||||||
/// Motion in the X direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
|
|
||||||
/// </summary>
|
|
||||||
internal LONG LastX;
|
|
||||||
/// <summary>
|
|
||||||
/// Motion in the Y direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
|
|
||||||
/// </summary>
|
|
||||||
internal LONG LastY;
|
|
||||||
/// <summary>
|
|
||||||
/// Device-specific additional information for the event.
|
|
||||||
/// </summary>
|
|
||||||
internal ULONG ExtraInformation;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mouse state. This member can be any reasonable combination of the following.
|
/// Mouse state. This member can be any reasonable combination of the following.
|
||||||
/// MOUSE_ATTRIBUTES_CHANGED
|
/// MOUSE_ATTRIBUTES_CHANGED
|
||||||
|
@ -2393,12 +2343,34 @@ namespace OpenTK.Platform.Windows
|
||||||
/// MOUSE_VIRTUAL_DESKTOP
|
/// MOUSE_VIRTUAL_DESKTOP
|
||||||
/// Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).
|
/// Mouse coordinates are mapped to the virtual desktop (for a multiple monitor system).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal RawMouseFlags Flags { get { return (RawMouseFlags)(flags); } }
|
[FieldOffset(0)] public RawMouseFlags Flags; // USHORT in winuser.h, but only INT works -- USHORT returns 0.
|
||||||
|
|
||||||
|
[FieldOffset(4)] public RawInputMouseState ButtonFlags;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Transition state of the mouse buttons.
|
/// If usButtonFlags is RI_MOUSE_WHEEL, this member is a signed value that specifies the wheel delta.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal RawInputMouseState ButtonFlags { get { return (RawInputMouseState)(buttonFlags); } }
|
[FieldOffset(6)] public USHORT ButtonData;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raw state of the mouse buttons.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(8)] public ULONG RawButtons;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Motion in the X direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(12)] public LONG LastX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Motion in the Y direction. This is signed relative motion or absolute motion, depending on the value of usFlags.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(16)] public LONG LastY;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Device-specific additional information for the event.
|
||||||
|
/// </summary>
|
||||||
|
[FieldOffset(20)] public ULONG ExtraInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -2483,10 +2455,11 @@ namespace OpenTK.Platform.Windows
|
||||||
/// Number of HID inputs in bRawData.
|
/// Number of HID inputs in bRawData.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal DWORD Count;
|
internal DWORD Count;
|
||||||
/// <summary>
|
// The RawData field must be marshalled manually.
|
||||||
/// Raw input data as an array of bytes.
|
///// <summary>
|
||||||
/// </summary>
|
///// Raw input data as an array of bytes.
|
||||||
internal BYTE RawData;
|
///// </summary>
|
||||||
|
//internal IntPtr RawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -3239,6 +3212,7 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Mouse indicator flags (found in winuser.h).
|
/// Mouse indicator flags (found in winuser.h).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Flags]
|
||||||
internal enum RawMouseFlags : ushort
|
internal enum RawMouseFlags : ushort
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -83,7 +83,10 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
if (System.Environment.OSVersion.Version.Major >= 5)
|
||||||
|
return new WinRawMouse();
|
||||||
|
else
|
||||||
|
return new WMInput(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -38,9 +38,10 @@ namespace OpenTK.Platform.Windows
|
||||||
Debug.Indent();
|
Debug.Indent();
|
||||||
|
|
||||||
AssignHandle(parent.WindowHandle);
|
AssignHandle(parent.WindowHandle);
|
||||||
|
WinWindowInfo win = new WinWindowInfo(this.Handle, parent);
|
||||||
Debug.Print("Input window attached to parent {0}", parent);
|
Debug.Print("Input window attached to parent {0}", parent);
|
||||||
keyboardDriver = new WinRawKeyboard(this.Handle);
|
keyboardDriver = new WinRawKeyboard(this.Handle);
|
||||||
mouseDriver = new WinRawMouse(this.Handle);
|
mouseDriver = new WinRawMouse();
|
||||||
|
|
||||||
Debug.Unindent();
|
Debug.Unindent();
|
||||||
|
|
||||||
|
@ -93,9 +94,7 @@ namespace OpenTK.Platform.Windows
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RawInputDeviceType.MOUSE:
|
case RawInputDeviceType.MOUSE:
|
||||||
if (!mouseDriver.ProcessEvent(data))
|
throw new NotSupportedException();
|
||||||
Functions.DefRawInputProc(ref data, 1, (uint)API.RawInputHeaderSize);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case RawInputDeviceType.HID:
|
case RawInputDeviceType.HID:
|
||||||
Functions.DefRawInputProc(ref data, 1, (uint)API.RawInputHeaderSize);
|
Functions.DefRawInputProc(ref data, 1, (uint)API.RawInputHeaderSize);
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
using OpenTK.Input;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System.Drawing;
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.Windows
|
namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
|
@ -19,54 +18,64 @@ namespace OpenTK.Platform.Windows
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains methods to register for and process mouse WM_INPUT messages.
|
/// Contains methods to register for and process mouse WM_INPUT messages.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class WinRawMouse : IMouseDriver, IDisposable
|
internal class WinRawMouse : IMouseDriver
|
||||||
{
|
{
|
||||||
private List<MouseDevice> mice = new List<MouseDevice>();
|
List<MouseState> mice;
|
||||||
private IntPtr window;
|
Dictionary<ContextHandle, int> rawids; // ContextHandle instead of IntPtr for fast dictionary access
|
||||||
|
readonly INativeWindow native;
|
||||||
#region --- Constructors ---
|
readonly IntPtr window;
|
||||||
|
readonly WindowProcedure WndProc;
|
||||||
|
readonly IntPtr OldWndProc;
|
||||||
|
|
||||||
internal WinRawMouse()
|
internal WinRawMouse()
|
||||||
: this(IntPtr.Zero)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
internal WinRawMouse(IntPtr windowHandle)
|
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Initializing mouse driver (WinRawMouse).");
|
Debug.WriteLine("Initializing mouse driver (WinRawMouse).");
|
||||||
Debug.Indent();
|
Debug.Indent();
|
||||||
|
|
||||||
this.window = windowHandle;
|
// Create a new message-only window to retrieve WM_INPUT messages.
|
||||||
|
native = new NativeWindow();
|
||||||
|
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();
|
||||||
|
|
||||||
RegisterDevices();
|
RegisterDevices(window, out mice, out rawids);
|
||||||
|
|
||||||
Debug.Unindent();
|
Debug.Unindent();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#region IMouseDriver Members
|
||||||
|
|
||||||
#region --- IMouseDriver Members ---
|
public IList<MouseDevice> Mouse { get { throw new NotImplementedException(); } }
|
||||||
|
|
||||||
public IList<MouseDevice> Mouse
|
|
||||||
{
|
|
||||||
get { return mice; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public MouseState GetState()
|
public MouseState GetState()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
native.ProcessEvents();
|
||||||
|
if (mice.Count > 0)
|
||||||
|
return mice[0];
|
||||||
|
else
|
||||||
|
return new MouseState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MouseState GetState(int index)
|
public MouseState GetState(int index)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
native.ProcessEvents();
|
||||||
|
if (index < mice.Count)
|
||||||
|
return mice[index];
|
||||||
|
else
|
||||||
|
return new MouseState();
|
||||||
}
|
}
|
||||||
|
|
||||||
#region public int RegisterDevices()
|
#endregion
|
||||||
|
|
||||||
public int RegisterDevices()
|
static int RegisterDevices(IntPtr window, out List<MouseState> mice, out Dictionary<ContextHandle, int> rawids)
|
||||||
{
|
{
|
||||||
int count = WinRawInput.DeviceCount;
|
int count = WinRawInput.DeviceCount;
|
||||||
|
mice = new List<MouseState>();
|
||||||
|
rawids = new Dictionary<ContextHandle, int>();
|
||||||
|
|
||||||
RawInputDeviceList[] ridl = new RawInputDeviceList[count];
|
RawInputDeviceList[] ridl = new RawInputDeviceList[count];
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
ridl[i] = new RawInputDeviceList();
|
ridl[i] = new RawInputDeviceList();
|
||||||
|
@ -114,22 +123,14 @@ namespace OpenTK.Platform.Windows
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
|
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
|
||||||
{
|
{
|
||||||
OpenTK.Input.MouseDevice mouse = new OpenTK.Input.MouseDevice();
|
// Register the device:
|
||||||
mouse.Description = deviceDesc;
|
|
||||||
|
|
||||||
// Register the keyboard:
|
|
||||||
RawInputDeviceInfo info = new RawInputDeviceInfo();
|
RawInputDeviceInfo info = new RawInputDeviceInfo();
|
||||||
int devInfoSize = API.RawInputDeviceInfoSize;
|
int devInfoSize = API.RawInputDeviceInfoSize;
|
||||||
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||||
info, ref devInfoSize);
|
info, ref devInfoSize);
|
||||||
|
|
||||||
mouse.NumberOfButtons = info.Device.Mouse.NumberOfButtons;
|
mice.Add(RegisterRawDevice(deviceDesc, window));
|
||||||
mouse.NumberOfWheels = info.Device.Mouse.HasHorizontalWheel ? 1 : 0;
|
rawids.Add(new ContextHandle(ridl[i].Device), mice.Count - 1);
|
||||||
|
|
||||||
mouse.DeviceID = ridl[i].Device;//(IntPtr)info.Device.Mouse.Id;
|
|
||||||
|
|
||||||
this.RegisterRawDevice(mouse);
|
|
||||||
mice.Add(mouse);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,14 +138,9 @@ namespace OpenTK.Platform.Windows
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
static MouseState RegisterRawDevice(string device, IntPtr window)
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region internal void RegisterRawDevice(OpenTK.Input.Mouse mouse)
|
|
||||||
|
|
||||||
internal void RegisterRawDevice(OpenTK.Input.MouseDevice mouse)
|
|
||||||
{
|
{
|
||||||
|
MouseState state = new MouseState();
|
||||||
RawInputDevice[] rid = new RawInputDevice[1];
|
RawInputDevice[] rid = new RawInputDevice[1];
|
||||||
// Mouse is 1/2 (page/id). See http://www.microsoft.com/whdc/device/input/HID_HWID.mspx
|
// Mouse is 1/2 (page/id). See http://www.microsoft.com/whdc/device/input/HID_HWID.mspx
|
||||||
rid[0] = new RawInputDevice();
|
rid[0] = new RawInputDevice();
|
||||||
|
@ -164,106 +160,96 @@ namespace OpenTK.Platform.Windows
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Print("Registered mouse {0}", mouse.ToString());
|
Debug.Print("Registered mouse {0}", device);
|
||||||
Point p = new Point();
|
Point p = new Point();
|
||||||
if (Functions.GetCursorPos(ref p))
|
if (Functions.GetCursorPos(ref p))
|
||||||
mouse.Position = p;
|
{
|
||||||
|
state.X = p.X;
|
||||||
|
state.Y = p.Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
IntPtr WindowProcedure(IntPtr handle, WindowMessage message, IntPtr wParam, IntPtr lParam)
|
||||||
|
|
||||||
#region internal bool ProcessEvent(API.RawInput rin)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Processes raw input events.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="rin"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal bool ProcessEvent(RawInput rin)
|
|
||||||
{
|
{
|
||||||
//MouseDevice mouse = mice.Find(delegate(MouseDevice m)
|
switch (message)
|
||||||
//{
|
|
||||||
// return m.DeviceID == rin.Header.Device;
|
|
||||||
//});
|
|
||||||
MouseDevice mouse;
|
|
||||||
if (mice.Count > 0) mouse = mice[0];
|
|
||||||
else return false;
|
|
||||||
|
|
||||||
switch (rin.Header.Type)
|
|
||||||
{
|
{
|
||||||
case RawInputDeviceType.MOUSE:
|
case WindowMessage.INPUT:
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0) mouse[MouseButton.Left] = true;
|
int expected_size = 0, real_size = 0;
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0) mouse[MouseButton.Left] = false;
|
RawInput data = new RawInput();
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0) mouse[MouseButton.Right] = true;
|
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0) mouse[MouseButton.Right] = false;
|
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0) mouse[MouseButton.Middle] = true;
|
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0) mouse[MouseButton.Middle] = false;
|
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0) mouse[MouseButton.Button1] = true;
|
|
||||||
if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0) mouse[MouseButton.Button1] = false;
|
|
||||||
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) != 0)
|
// Get the size of the input buffer
|
||||||
mouse.Wheel += (short)rin.Data.Mouse.ButtonData / 120;
|
Functions.GetRawInputData(lParam, GetRawInputDataEnum.INPUT,
|
||||||
|
IntPtr.Zero, ref expected_size, API.RawInputHeaderSize);
|
||||||
if ((rin.Data.Mouse.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
|
||||||
{
|
|
||||||
mouse.Position = new Point(rin.Data.Mouse.LastX, rin.Data.Mouse.LastY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Seems like MOUSE_MOVE_RELATIVE is the default, unless otherwise noted.
|
|
||||||
mouse.Position = new Point(mouse.X + rin.Data.Mouse.LastX,
|
|
||||||
mouse.Y + rin.Data.Mouse.LastY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((rin.Data.Mouse.Flags & RawMouseFlags.MOUSE_VIRTUAL_DESKTOP) != 0)
|
|
||||||
Debug.WriteLine(String.Format("Mouse {0} defines MOUSE_VIRTUAL_DESKTOP flag, please report at http://www.opentk.com", mouse.ToString()));
|
|
||||||
|
|
||||||
return true;
|
// 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:
|
default:
|
||||||
throw new ApplicationException("WinRawMouse driver received invalid data.");
|
return Functions.CallWindowProc(OldWndProc, handle, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
bool ProcessEvent(IntPtr device, RawMouse raw)
|
||||||
|
|
||||||
#region public void Poll()
|
|
||||||
|
|
||||||
public void Poll()
|
|
||||||
{
|
{
|
||||||
}
|
if (mice.Count == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
#endregion
|
ContextHandle handle = new ContextHandle(device);
|
||||||
|
MouseState mouse;
|
||||||
|
if (rawids.ContainsKey(handle))
|
||||||
|
mouse = mice[rawids[handle]];
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
#region --- IDisposable Members ---
|
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Left);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Left);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Right);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Right);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0) mouse.EnableBit((int)MouseButton.Middle);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0) mouse.DisableBit((int)MouseButton.Middle);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0) mouse.EnableBit((int)MouseButton.Button1);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0) mouse.DisableBit((int)MouseButton.Button1);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0) mouse.EnableBit((int)MouseButton.Button2);
|
||||||
|
if ((raw.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0) mouse.DisableBit((int)MouseButton.Button2);
|
||||||
|
|
||||||
private bool disposed;
|
if ((raw.ButtonFlags & RawInputMouseState.WHEEL) != 0)
|
||||||
|
mouse.WheelPrecise += (short)raw.ButtonData / 120.0f;
|
||||||
|
|
||||||
public void Dispose()
|
if ((raw.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
|
||||||
{
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Dispose(bool manual)
|
|
||||||
{
|
|
||||||
if (!disposed)
|
|
||||||
{
|
{
|
||||||
if (manual)
|
mouse.X = raw.LastX;
|
||||||
{
|
mouse.Y = raw.LastY;
|
||||||
mice.Clear();
|
|
||||||
}
|
|
||||||
disposed = true;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{ // Seems like MOUSE_MOVE_RELATIVE is the default, unless otherwise noted.
|
||||||
|
mouse.X += raw.LastX;
|
||||||
|
mouse.Y += raw.LastY;
|
||||||
|
}
|
||||||
|
|
||||||
|
mice[rawids[handle]] = mouse;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
~WinRawMouse()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue