mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-22 12:41:08 +00:00
* OpenTK.csproj:
* Input/MouseState.cs: * Platform/X11/Structs.cs: * Platform/X11/XI2Mouse.cs: * Platform/X11/Functions.cs: * Platform/X11/X11Factory.cs: Added XInput2 driver for mice. Multi-mouse support pending. * Platform/X11/X11Mouse.cs: Log the driver type for debugging purposes.
This commit is contained in:
parent
e638652d01
commit
671457b60a
|
@ -207,6 +207,44 @@ namespace OpenTK.Input
|
||||||
return !left.Equals(right);
|
return !left.Equals(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares to an object instance for equality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">
|
||||||
|
/// The <see cref="System.Object"/> to compare to.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// True if this instance is equal to obj; false otherwise.
|
||||||
|
/// </returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is MouseState)
|
||||||
|
{
|
||||||
|
return this == (MouseState)obj;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generates a hashcode for the current instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="System.Int32"/> represting the hashcode for this instance.
|
||||||
|
/// </returns>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (int* b = Buttons)
|
||||||
|
{
|
||||||
|
return b->GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ WheelPrecise.GetHashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal Members
|
#region Internal Members
|
||||||
|
|
|
@ -762,6 +762,7 @@
|
||||||
<Compile Include="Platform\X11\X11Keyboard.cs" />
|
<Compile Include="Platform\X11\X11Keyboard.cs" />
|
||||||
<Compile Include="Platform\X11\X11Mouse.cs" />
|
<Compile Include="Platform\X11\X11Mouse.cs" />
|
||||||
<Compile Include="Input\ButtonState.cs" />
|
<Compile Include="Input\ButtonState.cs" />
|
||||||
|
<Compile Include="Platform\X11\XI2Mouse.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
@ -94,7 +94,16 @@ namespace OpenTK.Platform.X11
|
||||||
public extern static Bool XCheckWindowEvent(Display display, Window w, EventMask event_mask, ref XEvent event_return);
|
public extern static Bool XCheckWindowEvent(Display display, Window w, EventMask event_mask, ref XEvent event_return);
|
||||||
[DllImport("libX11")]
|
[DllImport("libX11")]
|
||||||
public extern static Bool XCheckTypedWindowEvent(Display display, Window w, XEventName event_type, ref XEvent event_return);
|
public extern static Bool XCheckTypedWindowEvent(Display display, Window w, XEventName event_type, ref XEvent event_return);
|
||||||
|
[DllImport("libX11")]
|
||||||
|
public extern static Bool XCheckTypedEvent(Display display, XEventName event_type, out XEvent event_return);
|
||||||
|
|
||||||
|
|
||||||
|
public delegate Bool EventPredicate(IntPtr display, ref XEvent e, IntPtr arg);
|
||||||
|
[DllImport("libX11")]
|
||||||
|
public extern static Bool XIfEvent(Display display, ref XEvent e, IntPtr predicate, IntPtr arg );
|
||||||
|
[DllImport("libX11")]
|
||||||
|
public extern static Bool XCheckIfEvent(Display display, ref XEvent e, IntPtr predicate, IntPtr arg );
|
||||||
|
|
||||||
[DllImport("libX11")]
|
[DllImport("libX11")]
|
||||||
public extern static int XConnectionNumber(IntPtr diplay);
|
public extern static int XConnectionNumber(IntPtr diplay);
|
||||||
[DllImport("libX11")]
|
[DllImport("libX11")]
|
||||||
|
@ -325,7 +334,7 @@ namespace OpenTK.Platform.X11
|
||||||
public extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
|
public extern static int XQueryBestCursor(IntPtr display, IntPtr drawable, int width, int height, out int best_width, out int best_height);
|
||||||
|
|
||||||
[DllImport("libX11", EntryPoint = "XQueryExtension")]
|
[DllImport("libX11", EntryPoint = "XQueryExtension")]
|
||||||
public extern static int XQueryExtension(IntPtr display, string extension_name, ref int major, ref int first_event, ref int first_error);
|
public extern static int XQueryExtension(IntPtr display, string extension_name, out int major, out int first_event, out int first_error);
|
||||||
|
|
||||||
[DllImport("libX11", EntryPoint = "XWhitePixel")]
|
[DllImport("libX11", EntryPoint = "XWhitePixel")]
|
||||||
public extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
|
public extern static IntPtr XWhitePixel(IntPtr display, int screen_no);
|
||||||
|
@ -462,6 +471,27 @@ namespace OpenTK.Platform.X11
|
||||||
[DllImport("libX11")]
|
[DllImport("libX11")]
|
||||||
public static extern int XRefreshKeyboardMapping(ref XMappingEvent event_map);
|
public static extern int XRefreshKeyboardMapping(ref XMappingEvent event_map);
|
||||||
|
|
||||||
|
[DllImport("libX11")]
|
||||||
|
public static extern int XGetEventData(IntPtr display, ref XGenericEventCookie cookie);
|
||||||
|
|
||||||
|
[DllImport("libX11")]
|
||||||
|
public static extern void XFreeEventData(IntPtr display, ref XGenericEventCookie cookie);
|
||||||
|
|
||||||
|
[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);
|
||||||
|
}
|
||||||
|
|
||||||
static readonly IntPtr CopyFromParent = IntPtr.Zero;
|
static readonly IntPtr CopyFromParent = IntPtr.Zero;
|
||||||
|
|
||||||
public static void SendNetWMMessage(X11WindowInfo window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
|
public static void SendNetWMMessage(X11WindowInfo window, IntPtr message_type, IntPtr l0, IntPtr l1, IntPtr l2)
|
||||||
|
|
|
@ -36,6 +36,10 @@ using System.Runtime.InteropServices;
|
||||||
// X11 Version
|
// X11 Version
|
||||||
namespace OpenTK.Platform.X11
|
namespace OpenTK.Platform.X11
|
||||||
{
|
{
|
||||||
|
using Bool = System.Boolean;
|
||||||
|
using Time = System.IntPtr;
|
||||||
|
using Window = System.IntPtr;
|
||||||
|
|
||||||
//
|
//
|
||||||
// In the structures below, fields of type long are mapped to IntPtr.
|
// In the structures below, fields of type long are mapped to IntPtr.
|
||||||
// This will work on all platforms where sizeof(long)==sizeof(void*), which
|
// This will work on all platforms where sizeof(long)==sizeof(void*), which
|
||||||
|
@ -545,6 +549,29 @@ namespace OpenTK.Platform.X11
|
||||||
public IntPtr pad23;
|
public IntPtr pad23;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct XGenericEvent
|
||||||
|
{
|
||||||
|
public int type; // of event. Always GenericEvent
|
||||||
|
public IntPtr serial; // # of last request processed
|
||||||
|
public bool send_event; // true if from SendEvent request
|
||||||
|
public IntPtr display; // Display the event was read from
|
||||||
|
public int extension; // major opcode of extension that caused the event
|
||||||
|
public int evtype; // actual event type.
|
||||||
|
}
|
||||||
|
|
||||||
|
internal struct XGenericEventCookie
|
||||||
|
{
|
||||||
|
public int type; // of event. Always GenericEvent
|
||||||
|
public IntPtr serial; // # of last request processed
|
||||||
|
public bool send_event; // true if from SendEvent request
|
||||||
|
public IntPtr display; // Display the event was read from
|
||||||
|
public int extension; // major opcode of extension that caused the event
|
||||||
|
public int evtype; // actual event type.
|
||||||
|
public uint cookie; // unique event cookie
|
||||||
|
public IntPtr data; // actual event data
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
internal struct XEvent
|
internal struct XEvent
|
||||||
{
|
{
|
||||||
|
@ -612,6 +639,10 @@ namespace OpenTK.Platform.X11
|
||||||
public XErrorEvent ErrorEvent;
|
public XErrorEvent ErrorEvent;
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public XKeymapEvent KeymapEvent;
|
public XKeymapEvent KeymapEvent;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public XGenericEvent GenericEvent;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public XGenericEventCookie GenericEventCookie;
|
||||||
|
|
||||||
//[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=24)]
|
//[MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=24)]
|
||||||
//[ FieldOffset(0) ] public int[] pad;
|
//[ FieldOffset(0) ] public int[] pad;
|
||||||
|
@ -753,6 +784,7 @@ namespace OpenTK.Platform.X11
|
||||||
ColormapNotify = 32,
|
ColormapNotify = 32,
|
||||||
ClientMessage = 33,
|
ClientMessage = 33,
|
||||||
MappingNotify = 34,
|
MappingNotify = 34,
|
||||||
|
GenericEvent = 35,
|
||||||
|
|
||||||
LASTEvent
|
LASTEvent
|
||||||
}
|
}
|
||||||
|
@ -1623,4 +1655,164 @@ namespace OpenTK.Platform.X11
|
||||||
XYPixmap = 1,
|
XYPixmap = 1,
|
||||||
ZPixmap
|
ZPixmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XInput2 structures
|
||||||
|
|
||||||
|
struct XIDeviceInfo
|
||||||
|
{
|
||||||
|
public int deviceid;
|
||||||
|
public IntPtr name; // byte*
|
||||||
|
public int use;
|
||||||
|
public int attachment;
|
||||||
|
public Bool enabled;
|
||||||
|
public int num_classes;
|
||||||
|
public IntPtr classes; // XIAnyClassInfo **
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIAnyClassInfo
|
||||||
|
{
|
||||||
|
public int type;
|
||||||
|
public int sourceid;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIDeviceEvent
|
||||||
|
{
|
||||||
|
public int type; /* GenericEvent */
|
||||||
|
public IntPtr serial; /* # of last request processed by server */
|
||||||
|
public bool send_event; /* true if this came from a SendEvent request */
|
||||||
|
public IntPtr display; /* Display the event was read from */
|
||||||
|
public int extension; /* XI extension offset */
|
||||||
|
public XIEventType evtype;
|
||||||
|
public Time time;
|
||||||
|
public int deviceid;
|
||||||
|
public int sourceid;
|
||||||
|
public int detail;
|
||||||
|
public Window root;
|
||||||
|
public Window @event;
|
||||||
|
public Window child;
|
||||||
|
public double root_x;
|
||||||
|
public double root_y;
|
||||||
|
public double event_x;
|
||||||
|
public double event_y;
|
||||||
|
public int flags;
|
||||||
|
public XIButtonState buttons;
|
||||||
|
public XIValuatorState valuators;
|
||||||
|
public XIModifierState mods;
|
||||||
|
public XIGroupState @group;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIRawEvent
|
||||||
|
{
|
||||||
|
public int type; /* GenericEvent */
|
||||||
|
public IntPtr serial; /* # of last request processed by server */
|
||||||
|
public Bool send_event; /* true if this came from a SendEvent request */
|
||||||
|
public IntPtr display; /* Display the event was read from */
|
||||||
|
public int extension; /* XI extension offset */
|
||||||
|
public XIEventType evtype; /* XI_RawKeyPress, XI_RawKeyRelease, etc. */
|
||||||
|
public Time time;
|
||||||
|
public int deviceid;
|
||||||
|
public int sourceid;
|
||||||
|
public int detail;
|
||||||
|
public int flags;
|
||||||
|
public XIValuatorState valuators;
|
||||||
|
public IntPtr raw_values; // double *
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIButtonState
|
||||||
|
{
|
||||||
|
public int mask_len;
|
||||||
|
public IntPtr mask; // byte*
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIModifierState
|
||||||
|
{
|
||||||
|
public int @base;
|
||||||
|
public int latched;
|
||||||
|
public int locked;
|
||||||
|
public int effective;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIGroupState
|
||||||
|
{
|
||||||
|
public int @base;
|
||||||
|
public int latched;
|
||||||
|
public int locked;
|
||||||
|
public int effective;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIValuatorState
|
||||||
|
{
|
||||||
|
public int mask_len;
|
||||||
|
public IntPtr mask; // byte*
|
||||||
|
public IntPtr values; // double*
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XIEventMask : IDisposable
|
||||||
|
{
|
||||||
|
public int deviceid; // 0 = XIAllDevices, 1 = XIAllMasterDevices
|
||||||
|
int mask_len;
|
||||||
|
unsafe XIEventMasks* mask;
|
||||||
|
|
||||||
|
public XIEventMask(int id, XIEventMasks m)
|
||||||
|
{
|
||||||
|
deviceid = id;
|
||||||
|
mask_len = sizeof(XIEventMasks);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
mask = (XIEventMasks*)Marshal.AllocHGlobal(mask_len);
|
||||||
|
*mask = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(new IntPtr((void*)mask));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum XIEventType
|
||||||
|
{
|
||||||
|
DeviceChanged = 1,
|
||||||
|
KeyPress,
|
||||||
|
KeyRelease,
|
||||||
|
ButtonPress,
|
||||||
|
ButtonRelease,
|
||||||
|
Motion,
|
||||||
|
Enter,
|
||||||
|
Leave,
|
||||||
|
FocusIn,
|
||||||
|
FocusOut,
|
||||||
|
HierarchyChanged,
|
||||||
|
PropertyEvent,
|
||||||
|
RawKeyPress,
|
||||||
|
RawKeyRelease,
|
||||||
|
RawButtonPress,
|
||||||
|
RawButtonRelease,
|
||||||
|
RawMotion,
|
||||||
|
LastEvent = RawMotion
|
||||||
|
}
|
||||||
|
|
||||||
|
enum XIEventMasks
|
||||||
|
{
|
||||||
|
DeviceChangedMask = (1 << (int)XIEventType.DeviceChanged),
|
||||||
|
KeyPressMask = (1 << (int)XIEventType.KeyPress),
|
||||||
|
KeyReleaseMask = (1 << (int)XIEventType.KeyRelease),
|
||||||
|
ButtonPressMask = (1 << (int)XIEventType.ButtonPress),
|
||||||
|
ButtonReleaseMask = (1 << (int)XIEventType.ButtonRelease),
|
||||||
|
MotionMask = (1 << (int)XIEventType.Motion),
|
||||||
|
EnterMask = (1 << (int)XIEventType.Enter),
|
||||||
|
LeaveMask = (1 << (int)XIEventType.Leave),
|
||||||
|
FocusInMask = (1 << (int)XIEventType.FocusIn),
|
||||||
|
FocusOutMask = (1 << (int)XIEventType.FocusOut),
|
||||||
|
HierarchyChangedMask = (1 << (int)XIEventType.HierarchyChanged),
|
||||||
|
PropertyEventMask = (1 << (int)XIEventType.PropertyEvent),
|
||||||
|
RawKeyPressMask = (1 << (int)XIEventType.RawKeyPress),
|
||||||
|
RawKeyReleaseMask = (1 << (int)XIEventType.RawKeyRelease),
|
||||||
|
RawButtonPressMask = (1 << (int)XIEventType.RawButtonPress),
|
||||||
|
RawButtonReleaseMask = (1 << (int)XIEventType.RawButtonRelease),
|
||||||
|
RawMotionMask = (1 << (int)XIEventType.RawMotion),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,14 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
public virtual OpenTK.Input.IMouseDriver CreateMouseDriver()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Only supported on xorg 1.7 or higher.
|
||||||
|
return new XI2Mouse(null);
|
||||||
|
}
|
||||||
|
catch (NotSupportedException) { }
|
||||||
|
|
||||||
|
// Should always be supported.
|
||||||
return new X11Mouse(null);
|
return new X11Mouse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using OpenTK.Input;
|
using OpenTK.Input;
|
||||||
|
|
||||||
namespace OpenTK.Platform.X11
|
namespace OpenTK.Platform.X11
|
||||||
|
@ -60,6 +61,8 @@ namespace OpenTK.Platform.X11
|
||||||
// IntPtr.Zero, IntPtr.Zero);
|
// IntPtr.Zero, IntPtr.Zero);
|
||||||
//Functions.XSelectInput(window.Display, window.RootWindow, new IntPtr((int)window.EventMask));
|
//Functions.XSelectInput(window.Display, window.RootWindow, new IntPtr((int)window.EventMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.WriteLine("Using X11Mouse.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
188
Source/OpenTK/Platform/X11/XI2Mouse.cs
Normal file
188
Source/OpenTK/Platform/X11/XI2Mouse.cs
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
#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 System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using OpenTK.Input;
|
||||||
|
|
||||||
|
namespace OpenTK.Platform.X11
|
||||||
|
{
|
||||||
|
// Todo: multi-mouse support. Right now we aggregate all data into a single mouse device.
|
||||||
|
// This should be easy: just read the device id and route the data to the correct device.
|
||||||
|
sealed class XI2Mouse : IMouseDriver
|
||||||
|
{
|
||||||
|
MouseState state = new MouseState();
|
||||||
|
X11WindowInfo window;
|
||||||
|
readonly int XIOpCode;
|
||||||
|
|
||||||
|
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||||
|
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||||
|
|
||||||
|
// Can either attach itself to the specified window or can hook the root window.
|
||||||
|
public XI2Mouse(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (new XLock(window.Display))
|
||||||
|
{
|
||||||
|
int major, ev, error;
|
||||||
|
if (Functions.XQueryExtension(window.Display, "XInputExtension", out major, out ev, out error) == 0)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("XInput2 not supported.");
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
XIOpCode = major;
|
||||||
|
|
||||||
|
using (XIEventMask mask = new XIEventMask(1, XIEventMasks.RawButtonPressMask |
|
||||||
|
XIEventMasks.RawButtonReleaseMask | XIEventMasks.RawMotionMask))
|
||||||
|
{
|
||||||
|
Functions.XISelectEvents(window.Display, window.WindowHandle, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.WriteLine("Using XI2Mouse.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Todo: remove this
|
||||||
|
public IList<MouseDevice> Mouse { get { throw new NotSupportedException(); } }
|
||||||
|
|
||||||
|
public MouseState GetState()
|
||||||
|
{
|
||||||
|
ProcessEvents();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MouseState GetState(int index)
|
||||||
|
{
|
||||||
|
ProcessEvents();
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessEvents()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
XEvent e = new XEvent();
|
||||||
|
XGenericEventCookie cookie;
|
||||||
|
|
||||||
|
using (new XLock(window.Display))
|
||||||
|
{
|
||||||
|
if (!Functions.XCheckIfEvent(window.Display, ref e, Predicate, new IntPtr(XIOpCode)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
cookie = e.GenericEventCookie;
|
||||||
|
if (Functions.XGetEventData(window.Display, ref cookie) != 0)
|
||||||
|
{
|
||||||
|
XIRawEvent raw = (XIRawEvent)
|
||||||
|
Marshal.PtrToStructure(cookie.data, typeof(XIRawEvent));
|
||||||
|
|
||||||
|
switch (raw.evtype)
|
||||||
|
{
|
||||||
|
case XIEventType.RawMotion:
|
||||||
|
if (IsBitSet(raw.valuators.mask, 0))
|
||||||
|
state.X += (int)BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 0));
|
||||||
|
if (IsBitSet(raw.valuators.mask, 1))
|
||||||
|
state.Y += (int)BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 8));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XIEventType.RawButtonPress:
|
||||||
|
switch (raw.detail)
|
||||||
|
{
|
||||||
|
case 1: state.EnableBit((int)MouseButton.Left); break;
|
||||||
|
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
||||||
|
case 3: state.EnableBit((int)MouseButton.Right); break;
|
||||||
|
case 4: state.WheelPrecise++; break;
|
||||||
|
case 5: state.WheelPrecise--; break;
|
||||||
|
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
||||||
|
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
||||||
|
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
||||||
|
case 9: state.EnableBit((int)MouseButton.Button4); break;
|
||||||
|
case 10: state.EnableBit((int)MouseButton.Button5); break;
|
||||||
|
case 11: state.EnableBit((int)MouseButton.Button6); break;
|
||||||
|
case 12: state.EnableBit((int)MouseButton.Button7); break;
|
||||||
|
case 13: state.EnableBit((int)MouseButton.Button8); break;
|
||||||
|
case 14: state.EnableBit((int)MouseButton.Button9); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XIEventType.RawButtonRelease:
|
||||||
|
switch (raw.detail)
|
||||||
|
{
|
||||||
|
case 1: state.DisableBit((int)MouseButton.Left); break;
|
||||||
|
case 2: state.DisableBit((int)MouseButton.Middle); break;
|
||||||
|
case 3: state.DisableBit((int)MouseButton.Right); break;
|
||||||
|
case 6: state.DisableBit((int)MouseButton.Button1); break;
|
||||||
|
case 7: state.DisableBit((int)MouseButton.Button2); break;
|
||||||
|
case 8: state.DisableBit((int)MouseButton.Button3); break;
|
||||||
|
case 9: state.DisableBit((int)MouseButton.Button4); break;
|
||||||
|
case 10: state.DisableBit((int)MouseButton.Button5); break;
|
||||||
|
case 11: state.DisableBit((int)MouseButton.Button6); break;
|
||||||
|
case 12: state.DisableBit((int)MouseButton.Button7); break;
|
||||||
|
case 13: state.DisableBit((int)MouseButton.Button8); break;
|
||||||
|
case 14: state.DisableBit((int)MouseButton.Button9); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Functions.XFreeEventData(window.Display, ref cookie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
|
||||||
|
{
|
||||||
|
return e.GenericEventCookie.extension == arg.ToInt32() &&
|
||||||
|
(e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
|
||||||
|
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonPress ||
|
||||||
|
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonRelease);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsBitSet(IntPtr mask, int bit)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
return (*((byte*)mask + (bit >> 3)) & (1 << (bit & 7))) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue