#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info */ #endregion #region --- Using directives --- using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using OpenTK.Input; #endregion namespace OpenTK.Platform.Windows { internal class WinRawInput : NativeWindow, IInputDriver { /// /// Input event data. /// private API.RawInput data = new API.RawInput(); /// /// The total number of input devices connected to this system. /// private static int deviceCount; private WinRawKeyboard keyboardDriver; #region --- Constructors --- internal WinRawInput(IntPtr parentHandle) { Debug.WriteLine("Initalizing windows raw input driver."); Debug.Indent(); AssignHandle(parentHandle); Debug.Print("Input window attached to parent {0}", this.Handle); keyboardDriver = new WinRawKeyboard(this.Handle); Debug.Unindent(); } #endregion internal static int DeviceCount { get { API.GetRawInputDeviceList(null, ref deviceCount, API.RawInputDeviceListSize); return deviceCount; } } /* /// /// Gets a value indicating whether the Device list has changed, for example /// by removing or adding a device. /// internal static bool DeviceListChanged { get { uint count = 0; if (API.GetRawInputDeviceList(null, ref count, API.RawInputDeviceListSize) == 0) { if (deviceCount == count) return true; deviceCount = count; return false; } else { throw new ApplicationException(String.Format( "Could not retrieve the count of Keyboard devices. Windows error: {0}", Marshal.GetLastWin32Error())); } } } */ #region protected override void WndProc(ref Message msg) int size = 0; /// /// Processes the input Windows Message, routing the data to the correct Keyboard, Mouse or HID. /// /// The WM_INPUT message, containing the data on the input event. protected override void WndProc(ref Message msg) { switch (msg.Msg) { case API.Constants.WM_INPUT: size = 0; // Get the size of the input data API.GetRawInputData(msg.LParam, API.GetRawInputDataEnum.INPUT, IntPtr.Zero, ref size, API.RawInputHeaderSize); //if (data == null || API.RawInputSize < size) //{ // throw new ApplicationException("Critical error when processing raw windows input."); //} if (size == API.GetRawInputData(msg.LParam, API.GetRawInputDataEnum.INPUT, data, ref size, API.RawInputHeaderSize)) { switch (data.Header.Type) { case API.RawInputDeviceType.KEYBOARD: keyboardDriver.ProcessKeyboardEvent(data); break; case API.RawInputDeviceType.MOUSE: //throw new NotImplementedException(); break; case API.RawInputDeviceType.HID: //throw new NotImplementedException(); break; } } else { throw new ApplicationException(String.Format( "GetRawInputData returned invalid data. Windows error {0}. Please file a bug at http://opentk.sourceforge.net", Marshal.GetLastWin32Error())); } break; case API.Constants.WM_CLOSE: case API.Constants.WM_DESTROY: Debug.Print("Input window detached from parent {0}.", Handle); ReleaseHandle(); break; case API.Constants.WM_QUIT: Debug.WriteLine("Input window quit."); break; } base.WndProc(ref msg); } #endregion #region --- IInputDriver Members --- IList Input.IInputDriver.InputDevices { get { throw new Exception("The method or operation is not implemented."); } } public IList Keyboard { get { return keyboardDriver.Keyboard; } } public IList Mouse { get { throw new Exception("The method or operation is not implemented."); } } #endregion #region IMouseDriver Members IList IMouseDriver.Mouse { get { throw new Exception("The method or operation is not implemented."); } } #endregion } }