[Input] Added Mouse.GetCursorPos() (WIP)

This commit is contained in:
thefiddler 2014-05-10 01:30:46 +02:00
parent cd7342b688
commit f4a3cab0e0
12 changed files with 452 additions and 124 deletions

View file

@ -301,6 +301,7 @@ namespace Examples.Tests
static int DrawMice(Graphics gfx, int line)
{
line++;
DrawString(gfx, String.Format("Cursor: {0}", OpenTK.Input.Mouse.GetCursorState()), line++);
DrawString(gfx, "Mouse:", line++);
for (int i = 0; i < 4; i++)
{

View file

@ -36,5 +36,6 @@ namespace OpenTK.Input
MouseState GetState();
MouseState GetState(int index);
void SetPosition(double x, double y);
MouseState GetCursorState();
}
}

View file

@ -48,8 +48,14 @@ namespace OpenTK.Input
/// <summary>
/// Retrieves the combined <see cref="OpenTK.Input.MouseState"/> for all specified mouse devices.
/// The X, Y and wheel values are defined in a hardware-specific coordinate system.
/// Pointer ballistics (acceleration) are NOT applied. Resolution is hardware-specific,
/// typically between 200 and 2000 DPI.
/// Use <see cref="OpenTK.Input.Mouse.GetState(int)"/> to retrieve the state of a specific mouse device.
/// Use <see cref="OpenTK.Input.Mouse.GetCursorState()"/> to retrieve the absolute coordinates of the mouse cursor.
/// Use <see cref="OpenTK.GameWindow.MouseMove"/> for event-based mouse input.
/// </summary>
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure containing the combined state of all mouse devices.</returns>
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure representing the combined state of all mouse devices.</returns>
public static MouseState GetState()
{
lock (SyncRoot)
@ -60,9 +66,15 @@ namespace OpenTK.Input
/// <summary>
/// Retrieves the <see cref="OpenTK.Input.MouseState"/> for the specified mouse device.
/// The X, Y and wheel values are defined in a hardware-specific coordinate system.
/// Pointer ballistics (acceleration) are NOT applied. Resolution is hardware-specific,
/// typically between 200 and 2000 DPI.
/// Use <see cref="OpenTK.Input.Mouse.GetState()"/> to retrieve the combined state of all mouse devices.
/// Use <see cref="OpenTK.Input.Mouse.GetCursorState()"/> to retrieve the absolute coordinates of the mouse cursor.
/// Use <see cref="OpenTK.GameWindow.MouseMove"/> for event-based mouse input.
/// </summary>
/// <param name="index">The index of the mouse device.</param>
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure containing the state for the specified mouse device.</returns>
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure representing the state for the specified mouse device.</returns>
public static MouseState GetState(int index)
{
if (index < 0)
@ -74,6 +86,23 @@ namespace OpenTK.Input
}
}
/// <summary>
/// Retreves the <see cref="OpenTK.Input.MouseState"/> for the mouse cursor.
/// The X and Y coordinates are defined in absolute desktop points, with the origin
/// placed at the top-left corner of <see cref="OpenTK.DisplayDevice.Default"/>.
/// Pointer ballistics (acceleration) are applied. Resolution is limited to the
/// resolution of the <see cref="OpenTK.DisplayDevice"/> containing the cursor,
/// typically between 96 and 120 DPI.
/// </summary>
/// <returns>A <see cref="OpenTK.Input.MouseState"/> structure representing the state of the mouse cursor.</returns>
public static MouseState GetCursorState()
{
lock (SyncRoot)
{
return driver.GetCursorState();
}
}
/// <summary>
///Moves the mouse cursor to the specified screen position.
/// </summary>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<ProjectType>Local</ProjectType>
@ -167,6 +167,7 @@
<Compile Include="Platform\Windows\WinInputBase.cs" />
<Compile Include="Platform\Windows\XInputJoystick.cs" />
<Compile Include="Platform\X11\Bindings\INotify.cs" />
<Compile Include="Platform\X11\Bindings\XI.cs" />
<Compile Include="ToolkitOptions.cs" />
<Compile Include="WindowBorder.cs">
<SubType>Code</SubType>

View file

@ -834,6 +834,14 @@ namespace OpenTK.Platform.MacOS
return new MouseState();
}
MouseState IMouseDriver2.GetCursorState()
{
var state = new MouseState();
state.SetIsConnected(true);
return state;
}
void IMouseDriver2.SetPosition(double x, double y)
{
CG.SetLocalEventsSuppressionInterval(0.0);

View file

@ -119,6 +119,24 @@ namespace OpenTK.Platform.SDL2
return new MouseState();
}
public MouseState GetCursorState()
{
int x, y;
var buttons = SDL.GetMouseState(out x, out y);
var state = new MouseState();
state.SetIsConnected(true);
state.X = x;
state.Y = y;
state[MouseButton.Left] = (buttons & ButtonFlags.Left) != 0;
state[MouseButton.Middle] = (buttons & ButtonFlags.Middle) != 0;
state[MouseButton.Right] = (buttons & ButtonFlags.Right) != 0;
state[MouseButton.Button1] = (buttons & ButtonFlags.X1) != 0;
state[MouseButton.Button2] = (buttons & ButtonFlags.X2) != 0;
return state;
}
public void SetPosition(double x, double y)
{
SDL.WarpMouseInWindow(IntPtr.Zero, (int)x, (int)y);

View file

@ -348,6 +348,30 @@ namespace OpenTK.Platform.Windows
Functions.SetCursorPos((int)x, (int)y);
}
public MouseState GetCursorState()
{
var state = new MouseState();
state.SetIsConnected(true);
POINT p = new POINT();
Functions.GetCursorPos(ref p);
bool left = Functions.GetKeyState(VirtualKeys.LBUTTON) != 0;
bool right = Functions.GetKeyState(VirtualKeys.RBUTTON) != 0;
bool middle = Functions.GetKeyState(VirtualKeys.MBUTTON) != 0;
bool x1 = Functions.GetKeyState(VirtualKeys.XBUTTON1) != 0;
bool x2 = Functions.GetKeyState(VirtualKeys.XBUTTON2) != 0;
state.X = p.X;
state.Y = p.Y;
state[MouseButton.Left] = left;
state[MouseButton.Right] = right;
state[MouseButton.Middle] = middle;
state[MouseButton.Button1] = x1;
state[MouseButton.Button2] = x2;
return state;
}
#endregion
}
}

View file

@ -0,0 +1,127 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2014 Stefanos Apostolopoulos for 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 System.Runtime.InteropServices;
using System.Text;
namespace OpenTK.Platform.X11
{
using Bool = Boolean;
using Cursor = IntPtr;
using Display = IntPtr;
using Status = ErrorCodes;
using Time = IntPtr;
using Window = IntPtr;
// Bindings for the XInput2 extension
class XI
{
const string lib = "libXi";
// mouse
internal static readonly IntPtr ButtonLeft = Functions.XInternAtom(API.DefaultDisplay, "Button Left", false);
internal static readonly IntPtr ButtonMiddle = Functions.XInternAtom(API.DefaultDisplay, "Button Middle", false);
internal static readonly IntPtr ButtonRight = Functions.XInternAtom(API.DefaultDisplay, "Button Right", false);
internal static readonly IntPtr ButtonWheelUp = Functions.XInternAtom(API.DefaultDisplay, "Button Wheel Up", false);
internal static readonly IntPtr ButtonWheelDown = Functions.XInternAtom(API.DefaultDisplay, "Button Wheel Down", false);
internal static readonly IntPtr ButtonWheelLeft = Functions.XInternAtom(API.DefaultDisplay, "Button Horiz Wheel Left", false);
internal static readonly IntPtr ButtonWheelRight = Functions.XInternAtom(API.DefaultDisplay, "Button Horiz Wheel Right", false);
internal static readonly IntPtr RelativeX = Functions.XInternAtom(API.DefaultDisplay, "Rel X", false);
internal static readonly IntPtr RelativeY = Functions.XInternAtom(API.DefaultDisplay, "Rel Y", false);
internal static readonly IntPtr RelativeHWheel = Functions.XInternAtom(API.DefaultDisplay, "Rel Horiz Wheel", false);
internal static readonly IntPtr RelativeVWheel = Functions.XInternAtom(API.DefaultDisplay, "Rel Vert Wheel", false);
internal static readonly IntPtr RelativeHScroll = Functions.XInternAtom(API.DefaultDisplay, "Rel Horiz Scroll", false);
internal static readonly IntPtr RelativeVScroll = Functions.XInternAtom(API.DefaultDisplay, "Rel Vert Scroll", false);
// multitouch
internal static readonly IntPtr TouchX = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Position X", false);
internal static readonly IntPtr TouchY = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Position Y", false);
internal static readonly IntPtr TouchMajor = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Touch Major", false);
internal static readonly IntPtr TouchMinor = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Touch Minor", false);
internal static readonly IntPtr TouchPressure = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Pressure", false);
internal static readonly IntPtr TouchId = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Tracking ID", false);
internal static readonly IntPtr TouchMaxContacts = Functions.XInternAtom(API.DefaultDisplay, "Max Contacts", false);
// tablet
internal static readonly IntPtr AbsoluteX = Functions.XInternAtom(API.DefaultDisplay, "Abs X", false);
internal static readonly IntPtr AbsoluteY = Functions.XInternAtom(API.DefaultDisplay, "Abs Y", false);
internal static readonly IntPtr AbsolutePressure = Functions.XInternAtom(API.DefaultDisplay, "Abs Pressure", false);
internal static readonly IntPtr AbsoluteTiltX = Functions.XInternAtom(API.DefaultDisplay, "Abs Tilt X", false);
internal static readonly IntPtr AbsoluteTiltY = Functions.XInternAtom(API.DefaultDisplay, "Abs Tilt Y", false);
internal static readonly IntPtr AbsoluteWheel = Functions.XInternAtom(API.DefaultDisplay, "Abs Wheel", false);
internal static readonly IntPtr AbsoluteDistance = Functions.XInternAtom(API.DefaultDisplay, "Abs Distance", false);
[DllImport(lib, EntryPoint = "XISelectEvents")]
static extern int SelectEvents(IntPtr dpy, Window win, [In] XIEventMask[] masks, int num_masks);
[DllImport(lib, EntryPoint = "XISelectEvents")]
static extern int SelectEvents(IntPtr dpy, Window win, [In] ref XIEventMask masks, int num_masks);
public static int SelectEvents(IntPtr dpy, Window win, XIEventMask[] masks)
{
return SelectEvents(dpy, win, masks, masks.Length);
}
public static int SelectEvents(IntPtr dpy, Window win, XIEventMask mask)
{
return SelectEvents(dpy, win, ref mask, 1);
}
[DllImport(lib, EntryPoint = "XIGrabDevice")]
static extern Status GrabDevice(IntPtr display, int deviceid, Window grab_window, Time time,
Cursor cursor, int grab_mode, int paired_device_mode, Bool owner_events, XIEventMask[] mask);
[DllImport(lib, EntryPoint = "XIUngrabDevice")]
static extern Status UngrabDevice(IntPtr display, int deviceid, Time time);
[DllImport(lib, EntryPoint = "XIWarpPointer")]
public static extern Bool XIWarpPointer(Display display,
int deviceid, Window src_w, Window dest_w,
double src_x, double src_y, int src_width, int src_height,
double dest_x, double dest_y);
[DllImport(lib, EntryPoint = "XIQueryDevice")]
public static extern IntPtr QueryDevice(Display display, int id, out int count);
[DllImport(lib, EntryPoint = "XIFreeDeviceInfo")]
public static extern void FreeDeviceInfo(IntPtr devices);
[DllImport(lib, EntryPoint = "XIQueryPointer")]
public static extern Bool QueryPointer(Display display,
int deviceid, Window win,
out Window root_return, out Window child_return,
out double root_x_return, out double root_y_return,
out double win_x_return, out double win_y_return,
out XIButtonState buttons_return, out XIModifierState modifiers_return,
out XIGroupState group_return);
[DllImport(lib, EntryPoint = "XIQueryVersion")]
internal static extern Status QueryVersion(Display display, ref int major, ref int minor);
}
}

View file

@ -516,34 +516,6 @@ namespace OpenTK.Platform.X11
[DllImport("libX11")]
public static extern void XSetClassHint(IntPtr display, IntPtr window, ref XClassHint hint);
[DllImport("libXi")]
static extern int XISelectEvents(IntPtr dpy, Window win, [In] XIEventMask[] masks, int num_masks);
[DllImport("libXi")]
static extern int XISelectEvents(IntPtr dpy, Window win, [In] ref XIEventMask masks, int num_masks);
public static int XISelectEvents(IntPtr dpy, Window win, XIEventMask[] masks)
{
return XISelectEvents(dpy, win, masks, masks.Length);
}
public static int XISelectEvents(IntPtr dpy, Window win, XIEventMask mask)
{
return XISelectEvents(dpy, win, ref mask, 1);
}
[DllImport("libXi")]
static extern Status XIGrabDevice(IntPtr display, int deviceid, Window grab_window, Time time,
Cursor cursor, int grab_mode, int paired_device_mode, Bool owner_events, XIEventMask[] mask);
[DllImport("libXi")]
static extern Status XIUngrabDevice(IntPtr display, int deviceid, Time time);
[DllImport("libXi")]
public static extern Bool XIWarpPointer(Display display,
int deviceid, Window src_w, Window dest_w,
double src_x, double src_y, int src_width, int src_height,
double dest_x, double dest_y);
static readonly IntPtr CopyFromParent = IntPtr.Zero;
public static void SendNetWMMessage(X11WindowInfo window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)

View file

@ -1671,6 +1671,13 @@ namespace OpenTK.Platform.X11
// XInput2 structures
enum XIClassType
{
Button = 1,
Valuator = 2,
Scroll = 3,
}
struct XIDeviceInfo
{
public int deviceid;
@ -1684,10 +1691,33 @@ namespace OpenTK.Platform.X11
struct XIAnyClassInfo
{
public int type;
public XIClassType type;
public int sourceid;
}
struct XIButtonClassInfo
{
}
[StructLayout(LayoutKind.Sequential)]
struct XIValuatorClassInfo
{
public Atom label;
public double max;
public double min;
public int mode;
public int number;
public int resolution;
public int sourceid;
public int type;
public double value;
}
struct XIScrollClassInfo
{
}
struct XIDeviceEvent
{
public int type; /* GenericEvent */

View file

@ -48,6 +48,7 @@ namespace OpenTK.Platform.X11
readonly IntPtr display;
readonly IntPtr root_window;
MouseState mouse = new MouseState();
MouseState cursor = new MouseState();
// When the mouse warps, "detach" the current location
// from the pointer.
@ -58,6 +59,7 @@ namespace OpenTK.Platform.X11
{
Debug.WriteLine("Using X11Mouse.");
mouse.IsConnected = true;
cursor.IsConnected = true;
display = API.DefaultDisplay;
root_window = Functions.XRootWindow(display, Functions.XDefaultScreen(display));
}
@ -78,6 +80,12 @@ namespace OpenTK.Platform.X11
return new MouseState();
}
public MouseState GetCursorState()
{
ProcessEvents();
return cursor;
}
public void SetPosition(double x, double y)
{
// Update the current location, otherwise the pointer
@ -97,14 +105,6 @@ namespace OpenTK.Platform.X11
}
}
void WriteBit(MouseButton offset, int enabled)
{
if (enabled != 0)
mouse.EnableBit((int)offset);
else
mouse.DisableBit((int)offset);
}
void ProcessEvents()
{
IntPtr root, child;
@ -117,6 +117,9 @@ namespace OpenTK.Platform.X11
Functions.XQueryPointer(display, window, out root, out child,
out root_x, out root_y, out win_x, out win_y, out buttons);
cursor.X = root_x;
cursor.Y = root_y;
if (!mouse_detached)
{
mouse.X = root_x;
@ -129,9 +132,9 @@ namespace OpenTK.Platform.X11
mouse_detached_x = root_x;
mouse_detached_y = root_y;
}
WriteBit(MouseButton.Left, buttons & (int)MouseMask.Button1Mask);
WriteBit(MouseButton.Middle, buttons & (int)MouseMask.Button2Mask);
WriteBit(MouseButton.Right, buttons & (int)MouseMask.Button3Mask);
cursor[MouseButton.Left] = mouse[MouseButton.Left] = (buttons & (int)MouseMask.Button1Mask) != 0;
cursor[MouseButton.Middle] = mouse[MouseButton.Middle] = (buttons & (int)MouseMask.Button2Mask) != 0;
cursor[MouseButton.Right] = mouse[MouseButton.Right] = (buttons & (int)MouseMask.Button3Mask) != 0;
// Note: this will never work right, wheel events have a duration of 0
// (yes, zero). They are impposible to catch via polling.
// After spending a week on this, I simply don't care anymore.
@ -142,9 +145,9 @@ namespace OpenTK.Platform.X11
// 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);
cursor[MouseButton.Button1] = mouse[MouseButton.Button1] = (buttons & (int)MouseMask.Button6Mask) != 0;
cursor[MouseButton.Button2] = mouse[MouseButton.Button2] = (buttons & (int)MouseMask.Button7Mask) != 0;
cursor[MouseButton.Button3] = mouse[MouseButton.Button3] = (buttons & (int)MouseMask.Button8Mask) != 0;
}
}
}

View file

@ -37,8 +37,15 @@ namespace OpenTK.Platform.X11
// This should be easy: just read the device id and route the data to the correct device.
sealed class XI2Mouse : IMouseDriver2
{
List<MouseState> mice = new List<MouseState>();
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps raw ids to mouse ids
class XIMouse
{
public MouseState State;
public XIDeviceInfo Info;
}
XIMouse master; // XIMouse for the mouse cursor
List<XIMouse> devices = new List<XIMouse>(); // List of connected mice
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps hardware device ids to XIMouse ids
internal readonly X11WindowInfo window;
internal static int XIOpCode { get; private set; }
static bool supported;
@ -72,12 +79,20 @@ namespace OpenTK.Platform.X11
if (!IsSupported(window.Display))
throw new NotSupportedException("XInput2 not supported.");
using (XIEventMask mask = new XIEventMask(1, XIEventMasks.RawButtonPressMask |
XIEventMasks.RawButtonReleaseMask | XIEventMasks.RawMotionMask))
using (new XLock(API.DefaultDisplay))
using (XIEventMask mask = new XIEventMask(1,
XIEventMasks.RawButtonPressMask |
XIEventMasks.RawButtonReleaseMask |
XIEventMasks.RawMotionMask |
XIEventMasks.MotionMask |
XIEventMasks.ButtonPressMask |
XIEventMasks.ButtonReleaseMask |
XIEventMasks.DeviceChangedMask))
{
Functions.XISelectEvents(window.Display, window.Handle, mask);
Functions.XISelectEvents(window.Display, window.RootWindow, mask);
XI.SelectEvents(window.Display, window.Handle, mask);
}
UpdateDevices();
}
// Checks whether XInput2 is supported on the specified display.
@ -90,14 +105,51 @@ namespace OpenTK.Platform.X11
using (new XLock(display))
{
int major, ev, error;
if (Functions.XQueryExtension(display, "XInputExtension", out major, out ev, out error) == 0)
if (Functions.XQueryExtension(display, "XInputExtension", out major, out ev, out error) != 0)
{
return false;
}
XIOpCode = major;
int minor = 2;
while (minor >= 0)
{
if (XI.QueryVersion(display, ref major, ref minor) == ErrorCodes.Success)
{
return true;
}
minor--;
}
}
}
return false;
}
void UpdateDevices()
{
int count;
unsafe
{
XIDeviceInfo* list = (XIDeviceInfo*)XI.QueryDevice(window.Display, 1, out count);
for (int i = 0; i < count; i++)
{
if (devices.Count < i)
{
devices.Add(new XIMouse());
}
XIMouse d = devices[i];
d.State.SetIsConnected(true);
d.Info = *(list + i);
// Map the hardware device id to the current XIMouse id
if (!rawids.ContainsKey(d.Info.deviceid))
{
rawids.Add(d.Info.deviceid, 0);
}
rawids[d.Info.deviceid] = i;
}
XI.FreeDeviceInfo((IntPtr)list);
}
return true;
}
#region IMouseDriver2 Members
@ -106,9 +158,9 @@ namespace OpenTK.Platform.X11
{
ProcessEvents();
MouseState master = new MouseState();
foreach (MouseState ms in mice)
foreach (var d in devices)
{
master.MergeBits(ms);
master.MergeBits(d.State);
}
return master;
}
@ -116,12 +168,17 @@ namespace OpenTK.Platform.X11
public MouseState GetState(int index)
{
ProcessEvents();
if (mice.Count > index)
return mice[index];
if (devices.Count > index)
return devices[index].State;
else
return new MouseState();
}
public MouseState GetCursorState()
{
return master.State;
}
public void SetPosition(double x, double y)
{
using (new XLock(window.Display))
@ -168,21 +225,78 @@ namespace OpenTK.Platform.X11
cookie = e.GenericEventCookie;
if (Functions.XGetEventData(window.Display, ref cookie) != 0)
{
switch ((XIEventType)cookie.evtype)
{
case XIEventType.RawMotion:
case XIEventType.RawButtonPress:
case XIEventType.RawButtonRelease:
// Delivered to all XIMouse instances
ProcessRawEvent(ref cookie);
break;
case XIEventType.Motion:
case XIEventType.ButtonPress:
case XIEventType.ButtonRelease:
// Delivered only to the actual mouse cursor XIMouse instance
ProcessEvent(ref cookie);
break;
case XIEventType.DeviceChanged:
UpdateDevices();
break;
}
}
Functions.XFreeEventData(window.Display, ref cookie);
}
}
}
void ProcessEvent(ref XGenericEventCookie cookie)
{
XIDeviceEvent e = (XIDeviceEvent)
Marshal.PtrToStructure(cookie.data, typeof(XIDeviceEvent));
master.State.SetIsConnected(true);
master.State.X = (int)Math.Round(e.root_x);
master.State.Y = (int)Math.Round(e.root_y);
}
void ProcessRawEvent(ref XGenericEventCookie cookie)
{
XIRawEvent raw = (XIRawEvent)
Marshal.PtrToStructure(cookie.data, typeof(XIRawEvent));
if (!rawids.ContainsKey(raw.deviceid))
{
mice.Add(new MouseState());
rawids.Add(raw.deviceid, mice.Count - 1);
Debug.Print("Unknown mouse device {0} encountered, ignoring.", raw.deviceid);
return;
}
MouseState state = mice[rawids[raw.deviceid]];
var d = devices[rawids[raw.deviceid]];
switch (raw.evtype)
{
case XIEventType.RawMotion:
double x = 0, y = 0;
double h = 0, v = 0;
for (int i = 0; i < d.Info.num_classes; i++)
{
unsafe
{
XIAnyClassInfo* info = (XIAnyClassInfo*)d.Info.classes + i;
switch (info->type)
{
case XIClassType.Valuator:
{
XIValuatorClassInfo* n = (XIValuatorClassInfo*)info;
}
break;
}
}
}
if (IsBitSet(raw.valuators.mask, 0))
{
x = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 0));
@ -191,7 +305,8 @@ namespace OpenTK.Platform.X11
{
y = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 8));
}
break;
/*
if (!CheckMouseWarp(x, y))
{
state.X += (int)x;
@ -235,13 +350,9 @@ namespace OpenTK.Platform.X11
case 13: state.DisableBit((int)MouseButton.Button8); break;
case 14: state.DisableBit((int)MouseButton.Button9); break;
}
break;
}
mice[rawids[raw.deviceid]] = state;
}
Functions.XFreeEventData(window.Display, ref cookie);
}
break;*/
}
//mice[rawids[raw.deviceid]] = state;
}
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
@ -249,7 +360,10 @@ namespace OpenTK.Platform.X11
return e.GenericEventCookie.extension == arg.ToInt32() &&
(e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonPress ||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonRelease);
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonRelease ||
e.GenericEventCookie.evtype == (int)XIEventType.Motion ||
e.GenericEventCookie.evtype == (int)XIEventType.ButtonPress ||
e.GenericEventCookie.evtype == (int)XIEventType.ButtonRelease);
}
static bool IsBitSet(IntPtr mask, int bit)