mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-05-04 21:42:14 +00:00
[X11] Improved XI2Mouse implementation
Horizontal and vertical smooth scrolling is now supported. Movement axes are now correctly identified. Device hotplugging has been improved.
This commit is contained in:
parent
2b16a641f0
commit
bba9c8c26f
|
@ -1678,6 +1678,12 @@ namespace OpenTK.Platform.X11
|
||||||
Scroll = 3,
|
Scroll = 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum XIScrollType
|
||||||
|
{
|
||||||
|
Vertical = 1,
|
||||||
|
Horizontal = 2
|
||||||
|
}
|
||||||
|
|
||||||
struct XIDeviceInfo
|
struct XIDeviceInfo
|
||||||
{
|
{
|
||||||
public int deviceid;
|
public int deviceid;
|
||||||
|
@ -1686,7 +1692,7 @@ namespace OpenTK.Platform.X11
|
||||||
public int attachment;
|
public int attachment;
|
||||||
public Bool enabled;
|
public Bool enabled;
|
||||||
public int num_classes;
|
public int num_classes;
|
||||||
public IntPtr classes; // XIAnyClassInfo **
|
public IntPtr classes; // XIAnyClassInfo**
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XIAnyClassInfo
|
struct XIAnyClassInfo
|
||||||
|
@ -1697,25 +1703,36 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
struct XIButtonClassInfo
|
struct XIButtonClassInfo
|
||||||
{
|
{
|
||||||
|
public XIClassType type;
|
||||||
|
public int sourceid;
|
||||||
|
public int num_buttons;
|
||||||
|
public IntPtr labels; // Atom*
|
||||||
|
public XIButtonState state;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
struct XIScrollClassInfo
|
||||||
|
{
|
||||||
|
public XIClassType type;
|
||||||
|
public int sourceid;
|
||||||
|
public int number;
|
||||||
|
public XIScrollType scroll_type;
|
||||||
|
public double increment;
|
||||||
|
public int flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
struct XIValuatorClassInfo
|
struct XIValuatorClassInfo
|
||||||
{
|
{
|
||||||
public Atom label;
|
public XIClassType type;
|
||||||
public double max;
|
|
||||||
public double min;
|
|
||||||
public int mode;
|
|
||||||
public int number;
|
|
||||||
public int resolution;
|
|
||||||
public int sourceid;
|
public int sourceid;
|
||||||
public int type;
|
public int number;
|
||||||
|
public IntPtr label;
|
||||||
|
public double min;
|
||||||
|
public double max;
|
||||||
public double value;
|
public double value;
|
||||||
}
|
public int resolution;
|
||||||
|
public int mode;
|
||||||
struct XIScrollClassInfo
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XIDeviceEvent
|
struct XIDeviceEvent
|
||||||
|
@ -1756,9 +1773,9 @@ namespace OpenTK.Platform.X11
|
||||||
public int deviceid;
|
public int deviceid;
|
||||||
public int sourceid;
|
public int sourceid;
|
||||||
public int detail;
|
public int detail;
|
||||||
public int flags;
|
public XIEventFlags flags;
|
||||||
public XIValuatorState valuators;
|
public XIValuatorState valuators;
|
||||||
public IntPtr raw_values; // double *
|
public IntPtr raw_values; // FP3232*
|
||||||
}
|
}
|
||||||
|
|
||||||
struct XIButtonState
|
struct XIButtonState
|
||||||
|
|
|
@ -40,15 +40,33 @@ namespace OpenTK.Platform.X11
|
||||||
class XIMouse
|
class XIMouse
|
||||||
{
|
{
|
||||||
public MouseState State;
|
public MouseState State;
|
||||||
public XIDeviceInfo Info;
|
public XIDeviceInfo DeviceInfo;
|
||||||
|
public XIScrollClassInfo ScrollX = new XIScrollClassInfo { number = -1 };
|
||||||
|
public XIScrollClassInfo ScrollY = new XIScrollClassInfo { number = -1 };
|
||||||
|
public XIValuatorClassInfo MotionX = new XIValuatorClassInfo { number = -1 };
|
||||||
|
public XIValuatorClassInfo MotionY = new XIValuatorClassInfo { number = -1 };
|
||||||
}
|
}
|
||||||
XIMouse master; // XIMouse for the mouse cursor
|
|
||||||
|
// Atoms
|
||||||
|
//static readonly IntPtr ButtonLeft;
|
||||||
|
//static readonly IntPtr ButtonMiddle;
|
||||||
|
////static readonly IntPtr ButtonRight;
|
||||||
|
//static readonly IntPtr ButtonWheelUp;
|
||||||
|
//static readonly IntPtr ButtonWheelDown;
|
||||||
|
//static readonly IntPtr ButtonWheelLeft;
|
||||||
|
//static readonly IntPtr ButtonWheelRight;
|
||||||
|
static readonly IntPtr RelX;
|
||||||
|
static readonly IntPtr RelY;
|
||||||
|
//static readonly IntPtr RelHorizScroll;
|
||||||
|
//static readonly IntPtr RelVertScroll;
|
||||||
|
//static readonly IntPtr RelHorizWheel;
|
||||||
|
//static readonly IntPtr RelVertWheel;
|
||||||
|
|
||||||
List<XIMouse> devices = new List<XIMouse>(); // List of connected mice
|
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
|
Dictionary<int, int> rawids = new Dictionary<int, int>(); // maps hardware device ids to XIMouse ids
|
||||||
|
|
||||||
internal readonly X11WindowInfo window;
|
internal readonly X11WindowInfo window;
|
||||||
internal static int XIOpCode { get; private set; }
|
internal static int XIOpCode { get; private set; }
|
||||||
static bool supported;
|
|
||||||
|
|
||||||
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
static readonly Functions.EventPredicate PredicateImpl = IsEventValid;
|
||||||
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
readonly IntPtr Predicate = Marshal.GetFunctionPointerForDelegate(PredicateImpl);
|
||||||
|
@ -63,6 +81,36 @@ namespace OpenTK.Platform.X11
|
||||||
MouseWarp? mouse_warp_event;
|
MouseWarp? mouse_warp_event;
|
||||||
int mouse_warp_event_count;
|
int mouse_warp_event_count;
|
||||||
|
|
||||||
|
static XI2Mouse()
|
||||||
|
{
|
||||||
|
using (new XLock(API.DefaultDisplay))
|
||||||
|
{
|
||||||
|
// Mouse
|
||||||
|
//ButtonLeft = Functions.XInternAtom(API.DefaultDisplay, "Button Left", false);
|
||||||
|
//ButtonMiddle = Functions.XInternAtom(API.DefaultDisplay, "Button Middle", false);
|
||||||
|
//ButtonRight = Functions.XInternAtom(API.DefaultDisplay, "Button Right", false);
|
||||||
|
//ButtonWheelUp = Functions.XInternAtom(API.DefaultDisplay, "Button Wheel Up", false);
|
||||||
|
//ButtonWheelDown = Functions.XInternAtom(API.DefaultDisplay, "Button Wheel Down", false);
|
||||||
|
//ButtonWheelLeft = Functions.XInternAtom(API.DefaultDisplay, "Button Horiz Wheel Left", false);
|
||||||
|
//ButtonWheelRight = Functions.XInternAtom(API.DefaultDisplay, "Button Horiz Wheel Right", false);
|
||||||
|
RelX = Functions.XInternAtom(API.DefaultDisplay, "Rel X", false);
|
||||||
|
RelY = Functions.XInternAtom(API.DefaultDisplay, "Rel Y", false);
|
||||||
|
//RelHorizWheel = Functions.XInternAtom(API.DefaultDisplay, "Rel Horiz Wheel", false);
|
||||||
|
//RelVertWheel = Functions.XInternAtom(API.DefaultDisplay, "Rel Vert Wheel", false);
|
||||||
|
//RelHorizScroll = Functions.XInternAtom(API.DefaultDisplay, "Rel Horiz Scroll", false);
|
||||||
|
//RelVertScroll = Functions.XInternAtom(API.DefaultDisplay, "Rel Vert Scroll", false);
|
||||||
|
|
||||||
|
// Multitouch
|
||||||
|
//TouchX = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Position X", false);
|
||||||
|
//TouchY = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Position Y", false);
|
||||||
|
//TouchMajor = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Touch Major", false);
|
||||||
|
//TouchMinor = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Touch Minor", false);
|
||||||
|
//TouchPressure = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Pressure", false);
|
||||||
|
//TouchId = Functions.XInternAtom(API.DefaultDisplay, "Abs MT Tracking ID", false);
|
||||||
|
//TouchMaxContacts = Functions.XInternAtom(API.DefaultDisplay, "Max Contacts", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public XI2Mouse()
|
public XI2Mouse()
|
||||||
{
|
{
|
||||||
Debug.WriteLine("Using XI2Mouse.");
|
Debug.WriteLine("Using XI2Mouse.");
|
||||||
|
@ -84,9 +132,6 @@ namespace OpenTK.Platform.X11
|
||||||
XIEventMasks.RawButtonPressMask |
|
XIEventMasks.RawButtonPressMask |
|
||||||
XIEventMasks.RawButtonReleaseMask |
|
XIEventMasks.RawButtonReleaseMask |
|
||||||
XIEventMasks.RawMotionMask |
|
XIEventMasks.RawMotionMask |
|
||||||
XIEventMasks.MotionMask |
|
|
||||||
XIEventMasks.ButtonPressMask |
|
|
||||||
XIEventMasks.ButtonReleaseMask |
|
|
||||||
XIEventMasks.DeviceChangedMask))
|
XIEventMasks.DeviceChangedMask))
|
||||||
{
|
{
|
||||||
XI.SelectEvents(window.Display, window.Handle, mask);
|
XI.SelectEvents(window.Display, window.Handle, mask);
|
||||||
|
@ -130,22 +175,81 @@ namespace OpenTK.Platform.X11
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
XIDeviceInfo* list = (XIDeviceInfo*)XI.QueryDevice(window.Display, 1, out count);
|
XIDeviceInfo* list = (XIDeviceInfo*)XI.QueryDevice(window.Display, 1, out count);
|
||||||
|
|
||||||
|
Debug.Print("Refreshing mouse device list");
|
||||||
|
Debug.Print("{0} mouse devices detected", count);
|
||||||
|
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (devices.Count < i)
|
if (devices.Count <= i)
|
||||||
{
|
{
|
||||||
devices.Add(new XIMouse());
|
devices.Add(new XIMouse());
|
||||||
}
|
}
|
||||||
XIMouse d = devices[i];
|
XIMouse d = devices[i];
|
||||||
d.State.SetIsConnected(true);
|
d.DeviceInfo = *(list + i);
|
||||||
d.Info = *(list + i);
|
d.State.SetIsConnected(d.DeviceInfo.enabled);
|
||||||
|
Debug.Print("Device {0} is {1} and has:",
|
||||||
|
i, d.DeviceInfo.enabled ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
// Decode the XIDeviceInfo to axes, buttons and scroll types
|
||||||
|
for (int j = 0; j < d.DeviceInfo.num_classes; j++)
|
||||||
|
{
|
||||||
|
XIAnyClassInfo* class_info = *((XIAnyClassInfo**)d.DeviceInfo.classes + j);
|
||||||
|
switch (class_info->type)
|
||||||
|
{
|
||||||
|
case XIClassType.Button:
|
||||||
|
{
|
||||||
|
XIButtonClassInfo* button = (XIButtonClassInfo*)class_info;
|
||||||
|
Debug.Print("\t{0} buttons", button->num_buttons);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XIClassType.Scroll:
|
||||||
|
{
|
||||||
|
XIScrollClassInfo* scroll = (XIScrollClassInfo*)class_info;
|
||||||
|
switch (scroll->scroll_type)
|
||||||
|
{
|
||||||
|
case XIScrollType.Vertical:
|
||||||
|
Debug.WriteLine("\tSmooth vertical scrolling");
|
||||||
|
d.ScrollY = *scroll;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XIScrollType.Horizontal:
|
||||||
|
Debug.WriteLine("\tSmooth horizontal scrolling");
|
||||||
|
d.ScrollX = *scroll;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Debug.Print("\tUnknown scrolling type {0}", scroll->scroll_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XIClassType.Valuator:
|
||||||
|
{
|
||||||
|
XIValuatorClassInfo* valuator = (XIValuatorClassInfo*)class_info;
|
||||||
|
if (valuator->label == RelX)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("\tRelative X movement");
|
||||||
|
d.MotionX = *valuator;
|
||||||
|
}
|
||||||
|
else if (valuator->label == RelY)
|
||||||
|
{
|
||||||
|
Debug.WriteLine("\tRelative Y movement");
|
||||||
|
d.MotionY = *valuator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Map the hardware device id to the current XIMouse id
|
// Map the hardware device id to the current XIMouse id
|
||||||
if (!rawids.ContainsKey(d.Info.deviceid))
|
if (!rawids.ContainsKey(d.DeviceInfo.deviceid))
|
||||||
{
|
{
|
||||||
rawids.Add(d.Info.deviceid, 0);
|
rawids.Add(d.DeviceInfo.deviceid, 0);
|
||||||
}
|
}
|
||||||
rawids[d.Info.deviceid] = i;
|
rawids[d.DeviceInfo.deviceid] = i;
|
||||||
}
|
}
|
||||||
XI.FreeDeviceInfo((IntPtr)list);
|
XI.FreeDeviceInfo((IntPtr)list);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +280,19 @@ namespace OpenTK.Platform.X11
|
||||||
|
|
||||||
public MouseState GetCursorState()
|
public MouseState GetCursorState()
|
||||||
{
|
{
|
||||||
return master.State;
|
IntPtr dummy;
|
||||||
|
int x, y, dummy2;
|
||||||
|
using (new XLock(window.Display))
|
||||||
|
{
|
||||||
|
Functions.XQueryPointer(window.Display, window.RootWindow,
|
||||||
|
out dummy, out dummy, out x, out y,
|
||||||
|
out dummy2, out dummy2, out dummy2);
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseState master = GetState();
|
||||||
|
master.X = x;
|
||||||
|
master.Y = y;
|
||||||
|
return master;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPosition(double x, double y)
|
public void SetPosition(double x, double y)
|
||||||
|
@ -235,13 +351,6 @@ namespace OpenTK.Platform.X11
|
||||||
ProcessRawEvent(ref cookie);
|
ProcessRawEvent(ref cookie);
|
||||||
break;
|
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:
|
case XIEventType.DeviceChanged:
|
||||||
UpdateDevices();
|
UpdateDevices();
|
||||||
break;
|
break;
|
||||||
|
@ -252,125 +361,122 @@ namespace OpenTK.Platform.X11
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
void ProcessRawEvent(ref XGenericEventCookie cookie)
|
||||||
{
|
|
||||||
XIRawEvent raw = (XIRawEvent)
|
|
||||||
Marshal.PtrToStructure(cookie.data, typeof(XIRawEvent));
|
|
||||||
|
|
||||||
if (!rawids.ContainsKey(raw.deviceid))
|
|
||||||
{
|
|
||||||
Debug.Print("Unknown mouse device {0} encountered, ignoring.", raw.deviceid);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
unsafe
|
||||||
{
|
{
|
||||||
XIAnyClassInfo* info = (XIAnyClassInfo*)d.Info.classes + i;
|
XIRawEvent* raw = (XIRawEvent*)cookie.data;
|
||||||
switch (info->type)
|
|
||||||
|
if (!rawids.ContainsKey(raw->deviceid))
|
||||||
{
|
{
|
||||||
case XIClassType.Valuator:
|
Debug.Print("Unknown mouse device {0} encountered, ignoring.", raw->deviceid);
|
||||||
{
|
return;
|
||||||
XIValuatorClassInfo* n = (XIValuatorClassInfo*)info;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsBitSet(raw.valuators.mask, 0))
|
var d = devices[rawids[raw->deviceid]];
|
||||||
|
|
||||||
|
switch (raw->evtype)
|
||||||
{
|
{
|
||||||
x = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 0));
|
case XIEventType.RawMotion:
|
||||||
|
{
|
||||||
|
// Check if this event contains position information
|
||||||
|
// Note: we use the raw values here, without pointer
|
||||||
|
// ballistics and any other modification.
|
||||||
|
double x = 0, y = 0;
|
||||||
|
if (IsBitSet(raw->valuators.mask, d.MotionX.number))
|
||||||
|
{
|
||||||
|
x = *((double*)raw->raw_values + d.MotionX.number);
|
||||||
}
|
}
|
||||||
if (IsBitSet(raw.valuators.mask, 1))
|
if (IsBitSet(raw->valuators.mask, d.MotionY.number))
|
||||||
{
|
{
|
||||||
y = BitConverter.Int64BitsToDouble(Marshal.ReadInt64(raw.raw_values, 8));
|
y = *((double*)raw->raw_values + d.MotionY.number);
|
||||||
}
|
}
|
||||||
break;
|
d.State.X += (int)Math.Round(x);
|
||||||
/*
|
d.State.Y += (int)Math.Round(y);
|
||||||
if (!CheckMouseWarp(x, y))
|
|
||||||
|
// Check if this event contains scrolling information
|
||||||
|
// Note: we use transformed (valuator) values here,
|
||||||
|
// because they seem to make more sense compared to
|
||||||
|
// the raw values (the XI2 docs are pretty scarce on
|
||||||
|
// how to use the raw values for scrolling.)
|
||||||
|
double h = 0, v = 0;
|
||||||
|
bool is_emulated = (raw->flags & XIEventFlags.PointerEmulated) != 0;
|
||||||
|
if (!is_emulated && IsBitSet(raw->valuators.mask, d.ScrollX.number))
|
||||||
{
|
{
|
||||||
state.X += (int)x;
|
h = *((double*)raw->valuators.values + d.ScrollX.number) / d.ScrollX.increment;
|
||||||
state.Y += (int)y;
|
if (Double.IsInfinity(h))
|
||||||
|
{
|
||||||
|
Debug.WriteLine("[XI2] Mouse horizontal scroll was infinity.");
|
||||||
|
h = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_emulated && IsBitSet(raw->valuators.mask, d.ScrollY.number))
|
||||||
|
{
|
||||||
|
v = *((double*)raw->valuators.values + d.ScrollY.number) / d.ScrollY.increment;
|
||||||
|
if (Double.IsInfinity(v))
|
||||||
|
{
|
||||||
|
Debug.WriteLine("[XI2] Mouse horizontal scroll was infinity.");
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
d.State.SetScrollRelative((float)h, (float)v);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XIEventType.RawButtonPress:
|
case XIEventType.RawButtonPress:
|
||||||
switch (raw.detail)
|
switch (raw->detail)
|
||||||
{
|
{
|
||||||
case 1: state.EnableBit((int)MouseButton.Left); break;
|
case 1: d.State.EnableBit((int)MouseButton.Left); break;
|
||||||
case 2: state.EnableBit((int)MouseButton.Middle); break;
|
case 2: d.State.EnableBit((int)MouseButton.Middle); break;
|
||||||
case 3: state.EnableBit((int)MouseButton.Right); break;
|
case 3: d.State.EnableBit((int)MouseButton.Right); break;
|
||||||
case 4: state.SetScrollRelative(0, 1); break;
|
case 6: d.State.EnableBit((int)MouseButton.Button1); break;
|
||||||
case 5: state.SetScrollRelative(0, -1); break;
|
case 7: d.State.EnableBit((int)MouseButton.Button2); break;
|
||||||
case 6: state.EnableBit((int)MouseButton.Button1); break;
|
case 8: d.State.EnableBit((int)MouseButton.Button3); break;
|
||||||
case 7: state.EnableBit((int)MouseButton.Button2); break;
|
case 9: d.State.EnableBit((int)MouseButton.Button4); break;
|
||||||
case 8: state.EnableBit((int)MouseButton.Button3); break;
|
case 10: d.State.EnableBit((int)MouseButton.Button5); break;
|
||||||
case 9: state.EnableBit((int)MouseButton.Button4); break;
|
case 11: d.State.EnableBit((int)MouseButton.Button6); break;
|
||||||
case 10: state.EnableBit((int)MouseButton.Button5); break;
|
case 12: d.State.EnableBit((int)MouseButton.Button7); break;
|
||||||
case 11: state.EnableBit((int)MouseButton.Button6); break;
|
case 13: d.State.EnableBit((int)MouseButton.Button8); break;
|
||||||
case 12: state.EnableBit((int)MouseButton.Button7); break;
|
case 14: d.State.EnableBit((int)MouseButton.Button9); break;
|
||||||
case 13: state.EnableBit((int)MouseButton.Button8); break;
|
|
||||||
case 14: state.EnableBit((int)MouseButton.Button9); break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XIEventType.RawButtonRelease:
|
case XIEventType.RawButtonRelease:
|
||||||
switch (raw.detail)
|
switch (raw->detail)
|
||||||
{
|
{
|
||||||
case 1: state.DisableBit((int)MouseButton.Left); break;
|
case 1: d.State.DisableBit((int)MouseButton.Left); break;
|
||||||
case 2: state.DisableBit((int)MouseButton.Middle); break;
|
case 2: d.State.DisableBit((int)MouseButton.Middle); break;
|
||||||
case 3: state.DisableBit((int)MouseButton.Right); break;
|
case 3: d.State.DisableBit((int)MouseButton.Right); break;
|
||||||
case 6: state.DisableBit((int)MouseButton.Button1); break;
|
case 6: d.State.DisableBit((int)MouseButton.Button1); break;
|
||||||
case 7: state.DisableBit((int)MouseButton.Button2); break;
|
case 7: d.State.DisableBit((int)MouseButton.Button2); break;
|
||||||
case 8: state.DisableBit((int)MouseButton.Button3); break;
|
case 8: d.State.DisableBit((int)MouseButton.Button3); break;
|
||||||
case 9: state.DisableBit((int)MouseButton.Button4); break;
|
case 9: d.State.DisableBit((int)MouseButton.Button4); break;
|
||||||
case 10: state.DisableBit((int)MouseButton.Button5); break;
|
case 10: d.State.DisableBit((int)MouseButton.Button5); break;
|
||||||
case 11: state.DisableBit((int)MouseButton.Button6); break;
|
case 11: d.State.DisableBit((int)MouseButton.Button6); break;
|
||||||
case 12: state.DisableBit((int)MouseButton.Button7); break;
|
case 12: d.State.DisableBit((int)MouseButton.Button7); break;
|
||||||
case 13: state.DisableBit((int)MouseButton.Button8); break;
|
case 13: d.State.DisableBit((int)MouseButton.Button8); break;
|
||||||
case 14: state.DisableBit((int)MouseButton.Button9); break;
|
case 14: d.State.DisableBit((int)MouseButton.Button9); break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;*/
|
|
||||||
}
|
}
|
||||||
//mice[rawids[raw.deviceid]] = state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
|
static bool IsEventValid(IntPtr display, ref XEvent e, IntPtr arg)
|
||||||
{
|
{
|
||||||
return e.GenericEventCookie.extension == arg.ToInt32() &&
|
return
|
||||||
(e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
|
(long)e.GenericEventCookie.extension == arg.ToInt64() &&
|
||||||
|
e.GenericEventCookie.evtype == (int)XIEventType.RawMotion ||
|
||||||
e.GenericEventCookie.evtype == (int)XIEventType.RawButtonPress ||
|
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.DeviceChanged;
|
||||||
e.GenericEventCookie.evtype == (int)XIEventType.ButtonPress ||
|
|
||||||
e.GenericEventCookie.evtype == (int)XIEventType.ButtonRelease);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsBitSet(IntPtr mask, int bit)
|
static bool IsBitSet(IntPtr mask, int bit)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
return (*((byte*)mask + (bit >> 3)) & (1 << (bit & 7))) != 0;
|
return bit >= 0 && (*((byte*)mask + (bit >> 3)) & (1 << (bit & 7))) != 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue