Implemented KeyboardState.IsConnected property.
Implemented WinRawKeyboard.RefreshDevices(). General code clean-up and beautification.
This commit is contained in:
parent
72a714126b
commit
4a8cb59028
3 changed files with 210 additions and 217 deletions
|
@ -43,6 +43,7 @@ namespace OpenTK.Input
|
|||
const int NumInts = ((int)Key.LastKey + IntSize - 1) / IntSize;
|
||||
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
|
||||
unsafe fixed int Keys[NumInts];
|
||||
bool is_connected;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -84,6 +85,12 @@ namespace OpenTK.Input
|
|||
return !ReadBit((int)key);
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get { return is_connected; }
|
||||
internal set { is_connected = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether two <see cref="KeyboardState" /> instances are equal.
|
||||
/// </summary>
|
||||
|
@ -219,6 +226,7 @@ namespace OpenTK.Input
|
|||
*(k1 + i) |= *(k2 + i);
|
||||
}
|
||||
}
|
||||
IsConnected |= other.IsConnected;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -25,55 +25,51 @@
|
|||
//
|
||||
#endregion
|
||||
|
||||
#region --- Using directives ---
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32;
|
||||
using OpenTK.Input;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal class WinRawKeyboard : IKeyboardDriver2
|
||||
sealed 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>();
|
||||
private IntPtr window;
|
||||
readonly IntPtr window;
|
||||
readonly object UpdateLock = new object();
|
||||
|
||||
#region --- Constructors ---
|
||||
#region Constructors
|
||||
|
||||
internal WinRawKeyboard()
|
||||
: this(IntPtr.Zero)
|
||||
{
|
||||
}
|
||||
|
||||
internal WinRawKeyboard(IntPtr windowHandle)
|
||||
public WinRawKeyboard(IntPtr windowHandle)
|
||||
{
|
||||
Debug.WriteLine("Initializing keyboard driver (WinRawKeyboard).");
|
||||
Debug.Indent();
|
||||
|
||||
this.window = windowHandle;
|
||||
|
||||
UpdateKeyboardList();
|
||||
RefreshDevices();
|
||||
|
||||
Debug.Unindent();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region UpdateKeyboardList
|
||||
#region Public Members
|
||||
|
||||
internal void UpdateKeyboardList()
|
||||
public void RefreshDevices()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
{
|
||||
for (int i = 0; i < keyboards.Count; i++)
|
||||
{
|
||||
KeyboardState state = keyboards[i];
|
||||
state.IsConnected = false;
|
||||
keyboards[i] = state;
|
||||
}
|
||||
|
||||
int count = WinRawInput.DeviceCount;
|
||||
RawInputDeviceList[] ridl = new RawInputDeviceList[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
|
@ -81,114 +77,51 @@ namespace OpenTK.Platform.Windows
|
|||
Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize);
|
||||
|
||||
// Discover keyboard devices:
|
||||
for (int i = 0; i < count; i++)
|
||||
foreach (RawInputDeviceList dev in ridl)
|
||||
{
|
||||
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);
|
||||
string name = GetDeviceName(dev);
|
||||
if (name.ToLower().Contains("root"))
|
||||
{
|
||||
// This is a terminal services device, skip it.
|
||||
continue;
|
||||
}
|
||||
else if (ridl[i].Type == RawInputDeviceType.KEYBOARD || ridl[i].Type == RawInputDeviceType.HID)
|
||||
else if (dev.Type == RawInputDeviceType.KEYBOARD || dev.Type == RawInputDeviceType.HID)
|
||||
{
|
||||
// This is a keyboard or USB keyboard device. In the latter case, discover if it really is a
|
||||
// keyboard device by qeurying the registry.
|
||||
RegistryKey regkey = GetRegistryKey(name);
|
||||
string deviceDesc = (string)regkey.GetValue("DeviceDesc");
|
||||
string deviceClass = (string)regkey.GetValue("Class");
|
||||
deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
|
||||
|
||||
// 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");
|
||||
string deviceClass =
|
||||
(string)regkey.GetValue("Class");
|
||||
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("keyboard"))
|
||||
{
|
||||
KeyboardDevice kb = new KeyboardDevice();
|
||||
kb.Description = deviceDesc;
|
||||
|
||||
// Register the keyboard:
|
||||
RawInputDeviceInfo info = new RawInputDeviceInfo();
|
||||
int devInfoSize = API.RawInputDeviceInfoSize;
|
||||
Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||
info, ref devInfoSize);
|
||||
|
||||
kb.NumberOfLeds = info.Device.Keyboard.NumberOfIndicators;
|
||||
kb.NumberOfFunctionKeys = info.Device.Keyboard.NumberOfFunctionKeys;
|
||||
kb.NumberOfKeys = info.Device.Keyboard.NumberOfKeysTotal;
|
||||
//kb.DeviceID = (info.Device.Keyboard.Type << 32) + info.Device.Keyboard.SubType;
|
||||
kb.DeviceID = ridl[i].Device;
|
||||
//KeyboardDevice kb = new KeyboardDevice();
|
||||
//kb.Description = deviceDesc;
|
||||
//kb.NumberOfLeds = info.Device.Keyboard.NumberOfIndicators;
|
||||
//kb.NumberOfFunctionKeys = info.Device.Keyboard.NumberOfFunctionKeys;
|
||||
//kb.NumberOfKeys = info.Device.Keyboard.NumberOfKeysTotal;
|
||||
//kb.DeviceID = dev.Device;
|
||||
|
||||
//if (!keyboards.Contains(kb))
|
||||
//{
|
||||
this.RegisterKeyboardDevice(kb);
|
||||
keyboards_old.Add(kb);
|
||||
//}
|
||||
|
||||
keyboards.Add(new KeyboardState());
|
||||
RegisterKeyboardDevice(window, deviceDesc);
|
||||
KeyboardState state = new KeyboardState();
|
||||
state.IsConnected = true;
|
||||
keyboards.Add(state);
|
||||
names.Add(deviceDesc);
|
||||
rawids.Add(new ContextHandle(ridl[i].Device), keyboards.Count - 1);
|
||||
rawids.Add(new ContextHandle(dev.Device), keyboards.Count - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal void RegisterKeyboardDevice(Keyboard kb)
|
||||
|
||||
internal void RegisterKeyboardDevice(KeyboardDevice kb)
|
||||
{
|
||||
RawInputDevice[] rid = new RawInputDevice[1];
|
||||
// Keyboard is 1/6 (page/id). See http://www.microsoft.com/whdc/device/input/HID_HWID.mspx
|
||||
rid[0] = new RawInputDevice();
|
||||
rid[0].UsagePage = 1;
|
||||
rid[0].Usage = 6;
|
||||
rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
|
||||
rid[0].Target = window;
|
||||
|
||||
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())
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Registered keyboard {0}", kb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region internal bool ProcessKeyboardEvent(API.RawInput rin)
|
||||
|
||||
/// <summary>
|
||||
/// Processes raw input events.
|
||||
/// </summary>
|
||||
/// <param name="rin"></param>
|
||||
/// <returns></returns>
|
||||
internal bool ProcessKeyboardEvent(RawInput rin)
|
||||
public bool ProcessKeyboardEvent(RawInput rin)
|
||||
{
|
||||
bool processed = false;
|
||||
|
||||
|
@ -200,8 +133,7 @@ namespace OpenTK.Platform.Windows
|
|||
KeyboardState keyboard;
|
||||
if (!rawids.ContainsKey(handle))
|
||||
{
|
||||
keyboards.Add(new KeyboardState());
|
||||
rawids.Add(handle, keyboards.Count - 1);
|
||||
RefreshDevices();
|
||||
}
|
||||
keyboard = keyboards[rawids[handle]];
|
||||
|
||||
|
@ -247,21 +179,63 @@ namespace OpenTK.Platform.Windows
|
|||
|
||||
#endregion
|
||||
|
||||
#region --- IInputDevice Members ---
|
||||
#region Private Members
|
||||
|
||||
public string Description
|
||||
static RegistryKey GetRegistryKey(string name)
|
||||
{
|
||||
get { throw new Exception("The method or operation is not implemented."); }
|
||||
// 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;
|
||||
}
|
||||
|
||||
public Input.InputDeviceType DeviceType
|
||||
static string GetDeviceName(RawInputDeviceList dev)
|
||||
{
|
||||
get { return Input.InputDeviceType.Keyboard; }
|
||||
uint size = 0;
|
||||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICENAME, IntPtr.Zero, ref size);
|
||||
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 void RegisterKeyboardDevice(IntPtr window, string name)
|
||||
{
|
||||
RawInputDevice[] rid = new RawInputDevice[1];
|
||||
// Keyboard is 1/6 (page/id). See http://www.microsoft.com/whdc/device/input/HID_HWID.mspx
|
||||
rid[0] = new RawInputDevice();
|
||||
rid[0].UsagePage = 1;
|
||||
rid[0].Usage = 6;
|
||||
rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
|
||||
rid[0].Target = window;
|
||||
|
||||
if (!Functions.RegisterRawInputDevices(rid, 1, API.RawInputDeviceSize))
|
||||
{
|
||||
Debug.Print("[Warning] Raw input registration failed with error: {0}. Device: {1}",
|
||||
Marshal.GetLastWin32Error(), rid[0].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Registered keyboard {0}", name);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region --- IKeyboardDriver Members ---
|
||||
#region IKeyboardDriver2 Members
|
||||
|
||||
public KeyboardState GetState()
|
||||
{
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32;
|
||||
using OpenTK.Input;
|
||||
|
@ -39,7 +38,7 @@ namespace OpenTK.Platform.Windows
|
|||
/// <summary>
|
||||
/// Contains methods to register for and process mouse WM_INPUT messages.
|
||||
/// </summary>
|
||||
internal class WinRawMouse : IMouseDriver2
|
||||
sealed class WinRawMouse : IMouseDriver2
|
||||
{
|
||||
readonly List<MouseState> mice = new List<MouseState>();
|
||||
readonly List<string> names = new List<string>();
|
||||
|
@ -47,6 +46,8 @@ namespace OpenTK.Platform.Windows
|
|||
readonly IntPtr Window;
|
||||
readonly object UpdateLock = new object();
|
||||
|
||||
#region Constructors
|
||||
|
||||
public WinRawMouse(IntPtr window)
|
||||
{
|
||||
Debug.WriteLine("Initializing mouse driver (WinRawMouse).");
|
||||
|
@ -61,34 +62,10 @@ namespace OpenTK.Platform.Windows
|
|||
Debug.Unindent();
|
||||
}
|
||||
|
||||
#region IMouseDriver Members
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
{
|
||||
MouseState master = new MouseState();
|
||||
foreach (MouseState ms in mice)
|
||||
{
|
||||
master.MergeBits(ms);
|
||||
}
|
||||
return master;
|
||||
}
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
lock (UpdateLock)
|
||||
{
|
||||
if (mice.Count > index)
|
||||
return mice[index];
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Members
|
||||
|
||||
public void RefreshDevices()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
|
@ -134,8 +111,8 @@ namespace OpenTK.Platform.Windows
|
|||
// 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");
|
||||
deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
|
||||
|
||||
if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
|
||||
{
|
||||
|
@ -147,7 +124,7 @@ namespace OpenTK.Platform.Windows
|
|||
Functions.GetRawInputDeviceInfo(dev.Device, RawInputDeviceInfoEnum.DEVICEINFO,
|
||||
info, ref devInfoSize);
|
||||
|
||||
RegisterRawDevice(deviceDesc, Window);
|
||||
RegisterRawDevice(Window, deviceDesc);
|
||||
MouseState state = new MouseState();
|
||||
state.IsConnected = true;
|
||||
mice.Add(state);
|
||||
|
@ -160,62 +137,6 @@ namespace OpenTK.Platform.Windows
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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();
|
||||
rid[0].UsagePage = 1;
|
||||
rid[0].Usage = 2;
|
||||
rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
|
||||
rid[0].Target = window;
|
||||
|
||||
if (!Functions.RegisterRawInputDevices(rid, 1, API.RawInputDeviceSize))
|
||||
{
|
||||
Debug.Print("[Warning] Raw input registration failed with error: {0}. Device: {1}",
|
||||
Marshal.GetLastWin32Error(), rid[0].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Registered mouse {0}", device);
|
||||
}
|
||||
}
|
||||
|
||||
public bool ProcessMouseEvent(RawInput rin)
|
||||
{
|
||||
RawMouse raw = rin.Data.Mouse;
|
||||
|
@ -259,5 +180,95 @@ namespace OpenTK.Platform.Windows
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Members
|
||||
|
||||
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(IntPtr window, string device)
|
||||
{
|
||||
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();
|
||||
rid[0].UsagePage = 1;
|
||||
rid[0].Usage = 2;
|
||||
rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
|
||||
rid[0].Target = window;
|
||||
|
||||
if (!Functions.RegisterRawInputDevices(rid, 1, API.RawInputDeviceSize))
|
||||
{
|
||||
Debug.Print("[Warning] Raw input registration failed with error: {0}. Device: {1}",
|
||||
Marshal.GetLastWin32Error(), rid[0].ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Registered mouse {0}", device);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMouseDriver2 Members
|
||||
|
||||
public MouseState GetState()
|
||||
{
|
||||
lock (UpdateLock)
|
||||
{
|
||||
MouseState master = new MouseState();
|
||||
foreach (MouseState ms in mice)
|
||||
{
|
||||
master.MergeBits(ms);
|
||||
}
|
||||
return master;
|
||||
}
|
||||
}
|
||||
|
||||
public MouseState GetState(int index)
|
||||
{
|
||||
lock (UpdateLock)
|
||||
{
|
||||
if (mice.Count > index)
|
||||
return mice[index];
|
||||
else
|
||||
return new MouseState();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue