diff --git a/Source/OpenTK/Input/ButtonState.cs b/Source/OpenTK/Input/ButtonState.cs
new file mode 100644
index 00000000..597611f8
--- /dev/null
+++ b/Source/OpenTK/Input/ButtonState.cs
@@ -0,0 +1,46 @@
+ #region License
+ //
+ // The Open Toolkit Library License
+ //
+ // Copyright (c) 2006 - 2010 the Open Toolkit library.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
+ // of this software and associated documentation files (the "Software"), to deal
+ // in the Software without restriction, including without limitation the rights to
+ // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ // the Software, and to permit persons to whom the Software is furnished to do
+ // so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in all
+ // copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ // OTHER DEALINGS IN THE SOFTWARE.
+ //
+ #endregion
+
+namespace OpenTK.Input
+{
+ ///
+ /// Enumerates possible mouse button states.
+ ///
+ public enum ButtonState
+ {
+ ///
+ /// Indicates that a mouse button is released.
+ ///
+ Released = 0,
+
+ ///
+ /// Indicates that a mouse button is pressed.
+ ///
+ Pressed = 1
+ }
+}
+
diff --git a/Source/OpenTK/Input/MouseState.cs b/Source/OpenTK/Input/MouseState.cs
index 77d044fb..feae30d5 100644
--- a/Source/OpenTK/Input/MouseState.cs
+++ b/Source/OpenTK/Input/MouseState.cs
@@ -42,6 +42,8 @@ namespace OpenTK.Input
const int NumInts = ((int)MouseButton.LastButton + 31) / 32;
// The following line triggers bogus CS0214 in gmcs 2.0.1, sigh...
unsafe fixed int Buttons[NumInts];
+ int x, y;
+ float wheel;
#endregion
@@ -51,7 +53,7 @@ namespace OpenTK.Input
/// Gets a indicating whether this button is down.
///
/// The to check.
- public bool IsKeyDown(MouseButton button)
+ public bool IsButtonDown(MouseButton button)
{
return ReadBit((int)button);
}
@@ -60,11 +62,151 @@ namespace OpenTK.Input
/// Gets a indicating whether this button is up.
///
/// The to check.
- public bool IsKeyUp(MouseButton button)
+ public bool IsButtonUp(MouseButton button)
{
return !ReadBit((int)button);
}
+ ///
+ /// Gets the absolute wheel position in integer units.
+ /// To support high-precision mice, it is recommended to use instead.
+ ///
+ public int Wheel
+ {
+ get { return (int)Math.Round(wheel, MidpointRounding.AwayFromZero); }
+ }
+
+ ///
+ /// Gets the absolute wheel position in floating-point units.
+ ///
+ public float WheelPrecise
+ {
+ get { return wheel; }
+ internal set
+ {
+ wheel = value;
+ }
+ }
+
+ ///
+ /// Gets an integer representing the absolute x position of the pointer, in window pixel coordinates.
+ ///
+ public int X
+ {
+ get { return x; }
+ internal set { x = value; }
+ }
+
+ ///
+ /// Gets an integer representing the absolute y position of the pointer, in window pixel coordinates.
+ ///
+ public int Y
+ {
+ get { return y; }
+ internal set { y = value; }
+ }
+
+ ///
+ /// Gets a System.Boolean indicating the state of the specified MouseButton.
+ ///
+ /// The MouseButton to check.
+ /// True if the MouseButton is pressed, false otherwise.
+ public bool this[MouseButton button]
+ {
+ get
+ {
+ return IsButtonDown(button);
+ }
+ }
+
+ ///
+ /// Gets a
+ public ButtonState LeftButton
+ {
+ get { return IsButtonDown(MouseButton.Left) ? ButtonState.Pressed : ButtonState.Released; }
+ }
+
+ ///
+ /// Gets a
+ public ButtonState MiddleButton
+ {
+ get { return IsButtonDown(MouseButton.Middle) ? ButtonState.Pressed : ButtonState.Released; }
+ }
+
+ ///
+ /// Gets a
+ public ButtonState RightButton
+ {
+ get { return IsButtonDown(MouseButton.Right) ? ButtonState.Pressed : ButtonState.Released; }
+ }
+
+ ///
+ /// Gets a
+ public ButtonState XButton1
+ {
+ get { return IsButtonDown(MouseButton.Button1) ? ButtonState.Pressed : ButtonState.Released; }
+ }
+
+ ///
+ /// Gets a
+ public ButtonState XButton2
+ {
+ get { return IsButtonDown(MouseButton.Button2) ? ButtonState.Pressed : ButtonState.Released; }
+ }
+
+ ///
+ /// Gets the absolute wheel position in integer units. This property is intended for XNA compatibility.
+ /// To support high-precision mice, it is recommended to use instead.
+ ///
+ public int ScrollWheelValue
+ {
+ get { return Wheel; }
+ }
+
+ ///
+ /// Checks whether two instances are equal.
+ ///
+ ///
+ /// A instance.
+ ///
+ ///
+ /// A instance.
+ ///
+ ///
+ /// True if both left is equal to right; false otherwise.
+ ///
+ public static bool operator ==(MouseState left, MouseState right)
+ {
+ return left.Equals(right);
+ }
+
+ ///
+ /// Checks whether two instances are not equal.
+ ///
+ ///
+ /// A instance.
+ ///
+ ///
+ /// A instance.
+ ///
+ ///
+ /// True if both left is not equal to right; false otherwise.
+ ///
+ public static bool operator !=(MouseState left, MouseState right)
+ {
+ return !left.Equals(right);
+ }
+
#endregion
#region Internal Members
@@ -128,6 +270,7 @@ namespace OpenTK.Input
for (int i = 0; equal && i < NumInts; i++)
equal &= *(b1 + i) == *(b2 + i);
}
+ equal &= X == other.X && Y == other.Y && WheelPrecise == other.WheelPrecise;
}
return equal;
}
diff --git a/Source/OpenTK/OpenTK.csproj b/Source/OpenTK/OpenTK.csproj
index 0510e48d..693d87bb 100644
--- a/Source/OpenTK/OpenTK.csproj
+++ b/Source/OpenTK/OpenTK.csproj
@@ -76,6 +76,9 @@
..\..\Binaries\OpenTK\Release\
+ none
+ 4
+ true
true
@@ -757,6 +760,8 @@
Always
+
+
diff --git a/Source/OpenTK/Platform/X11/X11Factory.cs b/Source/OpenTK/Platform/X11/X11Factory.cs
index fd9cb473..b1212377 100644
--- a/Source/OpenTK/Platform/X11/X11Factory.cs
+++ b/Source/OpenTK/Platform/X11/X11Factory.cs
@@ -85,8 +85,7 @@ namespace OpenTK.Platform.X11
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
{
- //return new X11Mouse(null);
- throw new NotImplementedException();
+ return new X11Mouse(null);
}
#endregion
diff --git a/Source/OpenTK/Platform/X11/X11Mouse.cs b/Source/OpenTK/Platform/X11/X11Mouse.cs
new file mode 100644
index 00000000..49c8bedc
--- /dev/null
+++ b/Source/OpenTK/Platform/X11/X11Mouse.cs
@@ -0,0 +1,173 @@
+ #region License
+ //
+ // The Open Toolkit Library License
+ //
+ // Copyright (c) 2006 - 2010 the Open Toolkit library.
+ //
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
+ // of this software and associated documentation files (the "Software"), to deal
+ // in the Software without restriction, including without limitation the rights to
+ // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ // the Software, and to permit persons to whom the Software is furnished to do
+ // so, subject to the following conditions:
+ //
+ // The above copyright notice and this permission notice shall be included in all
+ // copies or substantial portions of the Software.
+ //
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ // OTHER DEALINGS IN THE SOFTWARE.
+ //
+ #endregion
+
+using System;
+using System.Collections.Generic;
+using OpenTK.Input;
+
+namespace OpenTK.Platform.X11
+{
+ sealed class X11Mouse : IMouseDriver
+ {
+ MouseState mouse = new MouseState();
+ X11WindowInfo window;
+
+ // Can either attach itself to the specified window or can hook the root window.
+ public X11Mouse(X11WindowInfo win)
+ {
+ if (win != null)
+ {
+ window = win;
+ }
+ else
+ {
+ using (new XLock(API.DefaultDisplay))
+ {
+ window = new X11WindowInfo();
+ window.Display = API.DefaultDisplay;
+ window.Screen = Functions.XDefaultScreen(window.Display);
+ window.RootWindow = Functions.XRootWindow(window.Display, window.Screen);
+ window.WindowHandle = window.RootWindow;
+ window.EventMask = EventMask.ButtonMotionMask |
+ EventMask.ButtonPressMask | EventMask.ButtonReleaseMask;
+
+ //Functions.XGrabPointer(window.Display, window.RootWindow, true,
+ // window.EventMask, GrabMode.GrabModeAsync, GrabMode.GrabModeAsync, IntPtr.Zero,
+ // IntPtr.Zero, IntPtr.Zero);
+ //Functions.XSelectInput(window.Display, window.RootWindow, new IntPtr((int)window.EventMask));
+ }
+ }
+ }
+
+ // Todo: remove this
+ public IList Mouse { get { throw new NotSupportedException(); } }
+
+ public MouseState GetState()
+ {
+ ProcessEvents();
+ return mouse;
+ }
+
+ public MouseState GetState(int index)
+ {
+
+ // X11Mouse supports a single mouse only
+ if (index < 0 || index > 1)
+ throw new ArgumentOutOfRangeException("index");
+
+ ProcessEvents();
+ return mouse;
+ }
+
+ void WriteBit(MouseButton offset, int enabled)
+ {
+ if (enabled != 0)
+ mouse.EnableBit((int)offset);
+ else
+ mouse.DisableBit((int)offset);
+ }
+
+ void ProcessEvents()
+ {
+ IntPtr root, child;
+ int root_x, root_y, win_x, win_y;
+ int buttons;
+ Functions.XQueryPointer(window.Display, window.WindowHandle, out root, out child,
+ out root_x, out root_y, out win_x, out win_y, out buttons);
+ mouse.X = root_x;
+ mouse.Y = root_y;
+ WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
+ WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
+ WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
+ if ((buttons & (int)MouseMask.Button4Mask) != 0)
+ mouse.WheelPrecise++;
+ if ((buttons & (int)MouseMask.Button5Mask) != 0)
+ mouse.WheelPrecise--;
+ WriteBit(MouseButton.Button1, buttons & (int)MouseMask.Button6Mask);
+ WriteBit(MouseButton.Button2, buttons & (int)MouseMask.Button7Mask);
+ WriteBit(MouseButton.Button3, buttons & (int)MouseMask.Button8Mask);
+
+// XEvent e = new XEvent();
+//
+// while (true)
+// {
+// using (new XLock(window.Display))
+// {
+// if (!Functions.XCheckWindowEvent(window.Display, window.WindowHandle, window.EventMask, ref e))
+// break;
+//
+// switch (e.type)
+// {
+// case XEventName.ButtonPress:
+// switch (e.ButtonEvent.button)
+// {
+// case 1: mouse.EnableBit((int)MouseButton.Left); break;
+// case 2: mouse.EnableBit((int)MouseButton.Middle); break;
+// case 3: mouse.EnableBit((int)MouseButton.Right); break;
+// case 4: mouse.WheelPrecise++; break;
+// case 5: mouse.WheelPrecise--; break;
+// case 6: mouse.EnableBit((int)MouseButton.Button1); break;
+// case 7: mouse.EnableBit((int)MouseButton.Button2); break;
+// case 8: mouse.EnableBit((int)MouseButton.Button3); break;
+// case 9: mouse.EnableBit((int)MouseButton.Button4); break;
+// case 10: mouse.EnableBit((int)MouseButton.Button5); break;
+// case 11: mouse.EnableBit((int)MouseButton.Button6); break;
+// case 12: mouse.EnableBit((int)MouseButton.Button7); break;
+// case 13: mouse.EnableBit((int)MouseButton.Button8); break;
+// case 15: mouse.EnableBit((int)MouseButton.Button9); break;
+// }
+// break;
+//
+// case XEventName.ButtonRelease:
+// switch (e.ButtonEvent.button)
+// {
+// case 1: mouse.DisableBit((int)MouseButton.Left); break;
+// case 2: mouse.DisableBit((int)MouseButton.Middle); break;
+// case 3: mouse.DisableBit((int)MouseButton.Right); break;
+// case 6: mouse.DisableBit((int)MouseButton.Button1); break;
+// case 7: mouse.DisableBit((int)MouseButton.Button2); break;
+// case 8: mouse.DisableBit((int)MouseButton.Button3); break;
+// case 9: mouse.DisableBit((int)MouseButton.Button4); break;
+// case 10: mouse.DisableBit((int)MouseButton.Button5); break;
+// case 11: mouse.DisableBit((int)MouseButton.Button6); break;
+// case 12: mouse.DisableBit((int)MouseButton.Button7); break;
+// case 13: mouse.DisableBit((int)MouseButton.Button8); break;
+// case 15: mouse.DisableBit((int)MouseButton.Button9); break;
+// }
+// break;
+//
+// case XEventName.MotionNotify:
+// mouse.X = e.MotionEvent.x;
+// mouse.Y = e.MotionEvent.y;
+// break;
+// }
+// }
+// }
+ }
+ }
+}
+