#region ================== Copyright (c) 2007 Pascal vd Heiden /* * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com * This program is released under GNU General Public License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * */ #endregion #region ================== Namespaces using System; using System.Windows.Forms; using CodeImp.DoomBuilder.Geometry; using System.Runtime.InteropServices; using System.Drawing; #endregion namespace CodeImp.DoomBuilder.Actions { internal class MouseInput : IDisposable { #region ================== Variables // Mouse input private RawMouse mouse; private bool firstProcess = true; private Point lastPos = new Point(); private Control source; #endregion #region ================== Constructor / Disposer // Constructor public MouseInput(Control source) { this.source = source; // Start mouse input try { mouse = new RawMouse(source); } catch { mouse = null; } // We have no destructor GC.SuppressFinalize(this); } // Disposer public void Dispose() { if(mouse != null) { mouse.Dispose(); mouse = null; } } #endregion #region ================== Methods #endregion #region ================== Processing // This processes the input public Vector2D Process() { float msX, msY; if (mouse != null) // Windows version where RawInput is available { MouseState ms = mouse.Poll(); msX = ms.X; msY = ms.Y; } else // Fallback implementation for unix { Point pos = Cursor.Position; Rectangle clipBox = source.RectangleToScreen(source.ClientRectangle); //Cursor.Clip; Cursor.Position = new Point(clipBox.X + clipBox.Width / 2, clipBox.Y + clipBox.Height / 2); if (firstProcess) { lastPos = Cursor.Position; firstProcess = false; } msX = (float)(pos.X - lastPos.X); msY = (float)(pos.Y - lastPos.Y); lastPos = Cursor.Position; } // Calculate changes depending on sensitivity float changex = msX * General.Settings.VisualMouseSensX * General.Settings.MouseSpeed * 0.01f; float changey = msY * General.Settings.VisualMouseSensY * General.Settings.MouseSpeed * 0.01f; return new Vector2D(changex, changey); } #endregion } public struct MouseState { public MouseState(float x, float y) { X = x; Y = y; } public float X { get; } public float Y { get; } } public class RawMouse { public RawMouse(System.Windows.Forms.Control control) { Handle = RawMouse_New(control.Handle); if (Handle == IntPtr.Zero) throw new Exception("RawMouse_New failed"); } ~RawMouse() { Dispose(); } public MouseState Poll() { return new MouseState(RawMouse_GetX(Handle), RawMouse_GetY(Handle)); } public bool Disposed { get { return Handle == IntPtr.Zero; } } public void Dispose() { if (!Disposed) { RawMouse_Delete(Handle); Handle = IntPtr.Zero; } } internal IntPtr Handle; [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern IntPtr RawMouse_New(IntPtr windowHandle); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern void RawMouse_Delete(IntPtr handle); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern float RawMouse_GetX(IntPtr handle); [DllImport("BuilderNative.dll", CallingConvention = CallingConvention.Cdecl)] static extern float RawMouse_GetY(IntPtr handle); } }