00001 #region --- License ---
00002
00003
00004
00005 #endregion
00006
00007 using System;
00008 using System.Collections.Generic;
00009 using System.Text;
00010 using OpenTK.Input;
00011 using System.Diagnostics;
00012 using System.Runtime.InteropServices;
00013 using Microsoft.Win32;
00014 using System.Drawing;
00015
00016 namespace OpenTK.Platform.Windows
00017 {
00022 internal class WinRawMouse : IMouseDriver, IDisposable
00023 {
00024 private List<MouseDevice> mice = new List<MouseDevice>();
00025 private IntPtr window;
00026
00027 #region --- Constructors ---
00028
00029 internal WinRawMouse()
00030 : this(IntPtr.Zero)
00031 {
00032 }
00033
00034 internal WinRawMouse(IntPtr windowHandle)
00035 {
00036 Debug.WriteLine("Initializing mouse driver (WinRawMouse).");
00037 Debug.Indent();
00038
00039 this.window = windowHandle;
00040
00041 RegisterDevices();
00042
00043 Debug.Unindent();
00044 }
00045
00046 #endregion
00047
00048 #region --- IMouseDriver Members ---
00049
00050 public IList<MouseDevice> Mouse
00051 {
00052 get { return mice; }
00053 }
00054
00055 #region public int RegisterDevices()
00056
00057 public int RegisterDevices()
00058 {
00059 int count = WinRawInput.DeviceCount;
00060 RawInputDeviceList[] ridl = new RawInputDeviceList[count];
00061 for (int i = 0; i < count; i++)
00062 ridl[i] = new RawInputDeviceList();
00063 Functions.GetRawInputDeviceList(ridl, ref count, API.RawInputDeviceListSize);
00064
00065
00066 for (int i = 0; i < count; i++)
00067 {
00068 uint size = 0;
00069 Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICENAME, IntPtr.Zero, ref size);
00070 IntPtr name_ptr = Marshal.AllocHGlobal((IntPtr)size);
00071 Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICENAME, name_ptr, ref size);
00072 string name = Marshal.PtrToStringAnsi(name_ptr);
00073 Marshal.FreeHGlobal(name_ptr);
00074
00075 if (name.ToLower().Contains("root"))
00076 {
00077
00078 continue;
00079 }
00080 else if (ridl[i].Type == RawInputDeviceType.MOUSE || ridl[i].Type == RawInputDeviceType.HID)
00081 {
00082
00083
00084
00085
00086
00087
00088 string[] split = name.Split('#');
00089
00090 string id_01 = split[0];
00091 string id_02 = split[1];
00092 string id_03 = split[2];
00093
00094
00095 string findme = string.Format(
00096 @"System\CurrentControlSet\Enum\{0}\{1}\{2}",
00097 id_01, id_02, id_03);
00098
00099 RegistryKey regkey = Registry.LocalMachine.OpenSubKey(findme);
00100
00101 string deviceDesc = (string)regkey.GetValue("DeviceDesc");
00102 deviceDesc = deviceDesc.Substring(deviceDesc.LastIndexOf(';') + 1);
00103 string deviceClass = (string)regkey.GetValue("Class");
00104
00105 if (!String.IsNullOrEmpty(deviceClass) && deviceClass.ToLower().Equals("mouse"))
00106 {
00107 OpenTK.Input.MouseDevice mouse = new OpenTK.Input.MouseDevice();
00108 mouse.Description = deviceDesc;
00109
00110
00111 RawInputDeviceInfo info = new RawInputDeviceInfo();
00112 int devInfoSize = API.RawInputDeviceInfoSize;
00113 Functions.GetRawInputDeviceInfo(ridl[i].Device, RawInputDeviceInfoEnum.DEVICEINFO,
00114 info, ref devInfoSize);
00115
00116 mouse.NumberOfButtons = info.Device.Mouse.NumberOfButtons;
00117 mouse.NumberOfWheels = info.Device.Mouse.HasHorizontalWheel ? 1 : 0;
00118
00119 mouse.DeviceID = ridl[i].Device;
00120
00121 this.RegisterRawDevice(mouse);
00122 mice.Add(mouse);
00123 }
00124 }
00125 }
00126
00127 return count;
00128 }
00129
00130 #endregion
00131
00132 #endregion
00133
00134 #region internal void RegisterRawDevice(OpenTK.Input.Mouse mouse)
00135
00136 internal void RegisterRawDevice(OpenTK.Input.MouseDevice mouse)
00137 {
00138 RawInputDevice[] rid = new RawInputDevice[1];
00139
00140 rid[0] = new RawInputDevice();
00141 rid[0].UsagePage = 1;
00142 rid[0].Usage = 2;
00143 rid[0].Flags = RawInputDeviceFlags.INPUTSINK;
00144 rid[0].Target = window;
00145
00146 if (!Functions.RegisterRawInputDevices(rid, 1, API.RawInputDeviceSize))
00147 {
00148 throw new ApplicationException(
00149 String.Format(
00150 "Raw input registration failed with error: {0}. Device: {1}",
00151 Marshal.GetLastWin32Error(),
00152 rid[0].ToString())
00153 );
00154 }
00155 else
00156 {
00157 Debug.Print("Registered mouse {0}", mouse.ToString());
00158 Point p = new Point();
00159 if (Functions.GetCursorPos(ref p))
00160 mouse.Position = p;
00161 }
00162 }
00163
00164 #endregion
00165
00166 #region internal bool ProcessEvent(API.RawInput rin)
00167
00173 internal bool ProcessEvent(RawInput rin)
00174 {
00175
00176
00177
00178
00179 MouseDevice mouse;
00180 if (mice.Count > 0) mouse = mice[0];
00181 else return false;
00182
00183 switch (rin.Header.Type)
00184 {
00185 case RawInputDeviceType.MOUSE:
00186 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.LEFT_BUTTON_DOWN) != 0) mouse[MouseButton.Left] = true;
00187 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.LEFT_BUTTON_UP) != 0) mouse[MouseButton.Left] = false;
00188 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_DOWN) != 0) mouse[MouseButton.Right] = true;
00189 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.RIGHT_BUTTON_UP) != 0) mouse[MouseButton.Right] = false;
00190 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_DOWN) != 0) mouse[MouseButton.Middle] = true;
00191 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.MIDDLE_BUTTON_UP) != 0) mouse[MouseButton.Middle] = false;
00192 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_4_DOWN) != 0) mouse[MouseButton.Button1] = true;
00193 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_4_UP) != 0) mouse[MouseButton.Button1] = false;
00194 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_5_DOWN) != 0) mouse[MouseButton.Button2] = true;
00195 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.BUTTON_5_UP) != 0) mouse[MouseButton.Button2] = false;
00196
00197 if ((rin.Data.Mouse.ButtonFlags & RawInputMouseState.WHEEL) != 0)
00198 mouse.Wheel += (short)rin.Data.Mouse.ButtonData / 120;
00199
00200 if ((rin.Data.Mouse.Flags & RawMouseFlags.MOUSE_MOVE_ABSOLUTE) != 0)
00201 {
00202 mouse.Position = new Point(rin.Data.Mouse.LastX, rin.Data.Mouse.LastY);
00203 }
00204 else
00205 {
00206 mouse.Position = new Point(mouse.X + rin.Data.Mouse.LastX,
00207 mouse.Y + rin.Data.Mouse.LastY);
00208 }
00209
00210 if ((rin.Data.Mouse.Flags & RawMouseFlags.MOUSE_VIRTUAL_DESKTOP) != 0)
00211 Debug.WriteLine(String.Format("Mouse {0} defines MOUSE_VIRTUAL_DESKTOP flag, please report at http://www.opentk.com", mouse.ToString()));
00212
00213 return true;
00214
00215 default:
00216 throw new ApplicationException("WinRawMouse driver received invalid data.");
00217 }
00218 }
00219
00220 #endregion
00221
00222 #region public void Poll()
00223
00224 public void Poll()
00225 {
00226 }
00227
00228 #endregion
00229
00230 #region --- IDisposable Members ---
00231
00232 private bool disposed;
00233
00234 public void Dispose()
00235 {
00236 Dispose(true);
00237 GC.SuppressFinalize(this);
00238 }
00239
00240 private void Dispose(bool manual)
00241 {
00242 if (!disposed)
00243 {
00244 if (manual)
00245 {
00246 mice.Clear();
00247 }
00248 disposed = true;
00249 }
00250 }
00251
00252 ~WinRawMouse()
00253 {
00254 Dispose(false);
00255 }
00256
00257 #endregion
00258 }
00259 }