[X11] Implemented high-resolution scroll events
This commit is contained in:
parent
9255fdcdb4
commit
c6dafbccba
4 changed files with 158 additions and 28 deletions
119
Source/OpenTK/Input/MouseScroll.cs
Normal file
119
Source/OpenTK/Input/MouseScroll.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
#region License
|
||||
//
|
||||
// MouseWheel.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace OpenTK.Input
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the state of a mouse wheel.
|
||||
/// </summary>
|
||||
public struct MouseScrollWheel : IEquatable<MouseScrollWheel>
|
||||
{
|
||||
#region Public Members
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute horizontal offset of the wheel,
|
||||
/// or 0 if no horizontal scroll wheel exists.
|
||||
/// </summary>
|
||||
/// <value>The x.</value>
|
||||
public float X { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the absolute vertical offset of the wheel,
|
||||
/// or 0 if no vertical scroll wheel exists.
|
||||
/// </summary>
|
||||
/// <value>The y.</value>
|
||||
public float Y { get; internal set; }
|
||||
|
||||
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for equality.</param>
|
||||
public static bool operator ==(MouseScrollWheel left, MouseScrollWheel right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <param name="left">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||
/// <param name="right">A <see cref="MouseScrollWheel"/> instance to test for inequality.</param>
|
||||
public static bool operator !=(MouseScrollWheel left, MouseScrollWheel right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String"/> that represents the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[X={0:0.00}, Y={1:0.00}]", X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serves as a hash function for a <see cref="OpenTK.Input.MouseScrollWheel"/> object.
|
||||
/// </summary>
|
||||
/// <returns>A hash code for this instance that is suitable for use in hashing algorithms and data structures such as a
|
||||
/// hash table.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="System.Object"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to the current
|
||||
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return
|
||||
obj is MouseScrollWheel &&
|
||||
Equals((MouseScrollWheel)obj);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IEquatable Members
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current <see cref="OpenTK.Input.MouseScrollWheel"/>.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="OpenTK.Input.MouseScrollWheel"/> to compare with the current <see cref="OpenTK.Input.MouseScrollWheel"/>.</param>
|
||||
/// <returns><c>true</c> if the specified <see cref="OpenTK.Input.MouseScrollWheel"/> is equal to the current
|
||||
/// <see cref="OpenTK.Input.MouseScrollWheel"/>; otherwise, <c>false</c>.</returns>
|
||||
public bool Equals(MouseScrollWheel other)
|
||||
{
|
||||
return X == other.X && Y == other.Y;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -132,6 +132,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
readonly bool xi2_supported;
|
||||
readonly int xi2_opcode;
|
||||
readonly int xi2_version;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -243,6 +244,7 @@ namespace OpenTK.Platform.X11
|
|||
if (xi2_supported)
|
||||
{
|
||||
xi2_opcode = XI2Mouse.XIOpCode;
|
||||
xi2_version = XI2Mouse.XIVersion;
|
||||
}
|
||||
|
||||
exists = true;
|
||||
|
@ -918,15 +920,29 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
case XEventName.ButtonPress:
|
||||
{
|
||||
int dx, dy;
|
||||
float dx, dy;
|
||||
MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
|
||||
|
||||
if (button != MouseButton.LastButton)
|
||||
{
|
||||
OnMouseDown(button);
|
||||
}
|
||||
else if (dx != 0 || dy != 0)
|
||||
|
||||
if (xi2_version >= 210)
|
||||
{
|
||||
// High resolution scroll events supported.
|
||||
// This code is implemented in XI2Mouse.GetCursorState().
|
||||
// Instead of reimplementing this functionality, just
|
||||
// use the values from there.
|
||||
MouseState state = Mouse.GetCursorState();
|
||||
dx = state.Scroll.X - MouseState.Scroll.X;
|
||||
dy = state.Scroll.Y - MouseState.Scroll.Y;
|
||||
}
|
||||
|
||||
if (dx != 0 || dy != 0)
|
||||
{
|
||||
// High resolution scroll events not supported
|
||||
// fallback to the old Button4-7 scroll buttons
|
||||
OnMouseWheel(dx, dy);
|
||||
}
|
||||
}
|
||||
|
@ -934,7 +950,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
case XEventName.ButtonRelease:
|
||||
{
|
||||
int dx, dy;
|
||||
float dx, dy;
|
||||
MouseButton button = X11KeyMap.TranslateButton(e.ButtonEvent.button, out dx, out dy);
|
||||
if (button != MouseButton.LastButton)
|
||||
{
|
||||
|
@ -1003,7 +1019,7 @@ namespace OpenTK.Platform.X11
|
|||
// RefreshWindowBorders();
|
||||
//}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
//Debug.WriteLine(String.Format("{0} event was not handled", e.type));
|
||||
break;
|
||||
|
@ -1499,11 +1515,8 @@ namespace OpenTK.Platform.X11
|
|||
void GrabMouse()
|
||||
{
|
||||
Functions.XGrabPointer(window.Display, window.Handle, false,
|
||||
EventMask.PointerMotionMask |
|
||||
EventMask.ButtonMotionMask | EventMask.Button1MotionMask |
|
||||
EventMask.Button2MotionMask | EventMask.Button3MotionMask |
|
||||
EventMask.Button4MotionMask | EventMask.Button5MotionMask |
|
||||
EventMask.ButtonPressMask | EventMask.ButtonReleaseMask,
|
||||
EventMask.PointerMotionMask | EventMask.ButtonPressMask |
|
||||
EventMask.ButtonReleaseMask,
|
||||
GrabMode.GrabModeAsync, GrabMode.GrabModeAsync,
|
||||
window.Handle, EmptyCursor, IntPtr.Zero);
|
||||
}
|
||||
|
|
|
@ -388,7 +388,7 @@ namespace OpenTK.Platform.X11
|
|||
return key != Key.Unknown;
|
||||
}
|
||||
|
||||
internal static MouseButton TranslateButton(int button, out int wheelx, out int wheely)
|
||||
internal static MouseButton TranslateButton(int button, out float wheelx, out float wheely)
|
||||
{
|
||||
wheelx = 0;
|
||||
wheely = 0;
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace OpenTK.Platform.X11
|
|||
|
||||
internal readonly X11WindowInfo window;
|
||||
internal static int XIOpCode { get; private set; }
|
||||
internal static int XIVersion { get; private set; }
|
||||
|
||||
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||
|
@ -172,6 +173,7 @@ namespace OpenTK.Platform.X11
|
|||
{
|
||||
if (XI.QueryVersion(display, ref major, ref minor) == ErrorCodes.Success)
|
||||
{
|
||||
XIVersion = major * 100 + minor * 10;
|
||||
return true;
|
||||
}
|
||||
minor--;
|
||||
|
@ -385,15 +387,13 @@ namespace OpenTK.Platform.X11
|
|||
case 1: d.State.EnableBit((int)MouseButton.Left); break;
|
||||
case 2: d.State.EnableBit((int)MouseButton.Middle); break;
|
||||
case 3: d.State.EnableBit((int)MouseButton.Right); break;
|
||||
case 6: d.State.EnableBit((int)MouseButton.Button1); break;
|
||||
case 7: d.State.EnableBit((int)MouseButton.Button2); break;
|
||||
case 8: d.State.EnableBit((int)MouseButton.Button3); break;
|
||||
case 9: d.State.EnableBit((int)MouseButton.Button4); break;
|
||||
case 10: d.State.EnableBit((int)MouseButton.Button5); break;
|
||||
case 11: d.State.EnableBit((int)MouseButton.Button6); break;
|
||||
case 12: d.State.EnableBit((int)MouseButton.Button7); break;
|
||||
case 13: d.State.EnableBit((int)MouseButton.Button8); break;
|
||||
case 14: d.State.EnableBit((int)MouseButton.Button9); break;
|
||||
case 8: d.State.EnableBit((int)MouseButton.Button1); break;
|
||||
case 9: d.State.EnableBit((int)MouseButton.Button2); break;
|
||||
case 10: d.State.EnableBit((int)MouseButton.Button3); break;
|
||||
case 11: d.State.EnableBit((int)MouseButton.Button4); break;
|
||||
case 12: d.State.EnableBit((int)MouseButton.Button5); break;
|
||||
case 13: d.State.EnableBit((int)MouseButton.Button6); break;
|
||||
case 14: d.State.EnableBit((int)MouseButton.Button7); break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -403,15 +403,13 @@ namespace OpenTK.Platform.X11
|
|||
case 1: d.State.DisableBit((int)MouseButton.Left); break;
|
||||
case 2: d.State.DisableBit((int)MouseButton.Middle); break;
|
||||
case 3: d.State.DisableBit((int)MouseButton.Right); break;
|
||||
case 6: d.State.DisableBit((int)MouseButton.Button1); break;
|
||||
case 7: d.State.DisableBit((int)MouseButton.Button2); break;
|
||||
case 8: d.State.DisableBit((int)MouseButton.Button3); break;
|
||||
case 9: d.State.DisableBit((int)MouseButton.Button4); break;
|
||||
case 10: d.State.DisableBit((int)MouseButton.Button5); break;
|
||||
case 11: d.State.DisableBit((int)MouseButton.Button6); break;
|
||||
case 12: d.State.DisableBit((int)MouseButton.Button7); break;
|
||||
case 13: d.State.DisableBit((int)MouseButton.Button8); break;
|
||||
case 14: d.State.DisableBit((int)MouseButton.Button9); break;
|
||||
case 8: d.State.DisableBit((int)MouseButton.Button1); break;
|
||||
case 9: d.State.DisableBit((int)MouseButton.Button2); break;
|
||||
case 10: d.State.DisableBit((int)MouseButton.Button3); break;
|
||||
case 11: d.State.DisableBit((int)MouseButton.Button4); break;
|
||||
case 12: d.State.DisableBit((int)MouseButton.Button5); break;
|
||||
case 13: d.State.DisableBit((int)MouseButton.Button6); break;
|
||||
case 14: d.State.DisableBit((int)MouseButton.Button7); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue