diff --git a/ThreeFingerDragOnWindows/Package.appxmanifest b/ThreeFingerDragOnWindows/Package.appxmanifest
index 29a481c..baf4a76 100644
--- a/ThreeFingerDragOnWindows/Package.appxmanifest
+++ b/ThreeFingerDragOnWindows/Package.appxmanifest
@@ -12,7 +12,7 @@
+ Version="2.0.5.0"/>
@@ -50,7 +50,7 @@
-
+
diff --git a/ThreeFingerDragOnWindows/ThreeFingerDragOnWindows.csproj b/ThreeFingerDragOnWindows/ThreeFingerDragOnWindows.csproj
index 58771af..591b059 100644
--- a/ThreeFingerDragOnWindows/ThreeFingerDragOnWindows.csproj
+++ b/ThreeFingerDragOnWindows/ThreeFingerDragOnWindows.csproj
@@ -16,17 +16,24 @@
https://github.com/ClementGre/ThreeFingerDragOnWindows
touchpad;tool;automation;finger
en
- 2.0.4.0
+ 2.0.5.0
MIT
ThreeFingerDragOnWindows
Three Finger Drag
False
Assets\icon.ico
True
- 6349A95D0136104C9F4661F4CF74E8F35FA2F9D2
- ThreeFingerDragOnWindows.pfx
- False
+
+
DISABLE_XAML_GENERATED_MAIN
+ False
+ SHA256
+ False
+ False
+ True
+ Never
+ 0
+ False
@@ -102,16 +109,16 @@
-
-
+
+
-
-
diff --git a/ThreeFingerDragOnWindows/settings/OtherSettings.xaml b/ThreeFingerDragOnWindows/settings/OtherSettings.xaml
index 9395050..aba7116 100644
--- a/ThreeFingerDragOnWindows/settings/OtherSettings.xaml
+++ b/ThreeFingerDragOnWindows/settings/OtherSettings.xaml
@@ -39,7 +39,7 @@
-
+
-
+
@@ -75,7 +75,7 @@
+ Text="Version 2.0.5.0" />
-
\ No newline at end of file
+
diff --git a/ThreeFingerDragOnWindows/touchpad/ContactsManager.cs b/ThreeFingerDragOnWindows/touchpad/ContactsManager.cs
index 3aac241..f0c4110 100644
--- a/ThreeFingerDragOnWindows/touchpad/ContactsManager.cs
+++ b/ThreeFingerDragOnWindows/touchpad/ContactsManager.cs
@@ -27,7 +27,7 @@ public ContactsManager(HandlerWindow source){
public void InitializeSource(){
var touchpadExists = TouchpadHelper.Exists();
var inputReceiverInstalled = TouchpadHelper.RegisterInput(_hwnd);
-
+
_source.OnTouchpadInitialized(touchpadExists, inputReceiverInstalled);
}
@@ -80,12 +80,12 @@ private void RegisterTouchpadContact(TouchpadContact contact){
}
_lastContacts.Add(contact);
}
-
+
private void SendLastContacts(){
// If contacts have all been released for a long time, cancel the last contact list
if(Ctms() - _lastSendContacts < 50 && _lastContacts.Count > 0)
_source.OnTouchpadContact(_lastContacts.ToArray());
-
+
_lastContacts.Clear();
_lastSendContacts = Ctms();
}
diff --git a/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs b/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs
index 7cb5f50..6d56c87 100644
--- a/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs
+++ b/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using ThreeFingerDragEngine.utils;
namespace ThreeFingerDragOnWindows.utils;
-// From emoacht/RawInput.Touchpad
-internal static class TouchpadHelper{
+// Code from emoacht/RawInput.Touchpad, edited by Clément Grennerat
+internal static class TouchpadHelper {
public const int WM_INPUT = 0x00FF;
public const int WM_INPUT_DEVICE_CHANGE = 0x00FE;
public const int RIM_INPUT = 0;
@@ -16,7 +15,7 @@ internal static class TouchpadHelper{
public static bool Exists(){
uint deviceListCount = 0;
- var rawInputDeviceListSize = (uint)Marshal.SizeOf();
+ var rawInputDeviceListSize = (uint) Marshal.SizeOf();
if(GetRawInputDeviceList(
null,
@@ -48,7 +47,7 @@ public static bool Exists(){
device.hDevice,
RIDI_DEVICEINFO,
ref deviceInfo,
- ref deviceInfoSize) == unchecked((uint)-1))
+ ref deviceInfoSize) == unchecked((uint) -1))
continue;
if(deviceInfo.hid.usUsagePage == 0x000D &&
@@ -69,7 +68,7 @@ public static bool RegisterInput(IntPtr hwndTarget){
hwndTarget = hwndTarget
};
- return RegisterRawInputDevices(new[]{ device }, 1, (uint)Marshal.SizeOf());
+ return RegisterRawInputDevices(new[]{ device }, 1, (uint) Marshal.SizeOf());
}
public static TouchpadContact[] ParseInput(IntPtr lParam){
@@ -127,7 +126,7 @@ public static TouchpadContact[] ParseInput(IntPtr lParam){
ref preparsedDataSize) != 0)
return null;
- preparsedDataPointer = Marshal.AllocHGlobal((int)preparsedDataSize);
+ preparsedDataPointer = Marshal.AllocHGlobal((int) preparsedDataSize);
if(GetRawInputDeviceInfo(
rawInput.Header.hDevice,
@@ -165,22 +164,23 @@ public static TouchpadContact[] ParseInput(IntPtr lParam){
// In case this valueCap contains multiple contacts at a time (rawInput.Hid.dwCount), iterates over each contact
for(int contactIndex = 0; contactIndex < rawInput.Hid.dwCount; contactIndex++){
toLog += contactIndex + ": ";
- IntPtr rawHidRawDataPointerAdjusted = IntPtr.Add(rawHidRawDataPointer, (int) (rawInput.Hid.dwSizeHid * contactIndex));
+ IntPtr rawHidRawDataPointerAdjusted = IntPtr.Add(rawHidRawDataPointer,
+ (int) (rawInput.Hid.dwSizeHid * contactIndex));
if(HidP_GetUsageValue(
- HIDP_REPORT_TYPE.HidP_Input,
- valueCap.UsagePage,
- valueCap.LinkCollection,
- valueCap.Usage,
- out var value,
- preparsedDataPointer,
- rawHidRawDataPointerAdjusted,
- (uint) rawHidRawData.Length) != HIDP_STATUS_SUCCESS)
+ HIDP_REPORT_TYPE.HidP_Input,
+ valueCap.UsagePage,
+ valueCap.LinkCollection,
+ valueCap.Usage,
+ out var value,
+ preparsedDataPointer,
+ rawHidRawDataPointerAdjusted,
+ (uint) rawHidRawData.Length) != HIDP_STATUS_SUCCESS)
continue;
// Usage Page and ID in Windows Precision Touchpad input reports
// https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections#windows-precision-touchpad-input-reports
- switch (valueCap.LinkCollection){
+ switch(valueCap.LinkCollection){
case 0:
switch (valueCap.UsagePage, valueCap.Usage){
case (0x0D, 0x56): // Scan Time
@@ -217,9 +217,11 @@ public static TouchpadContact[] ParseInput(IntPtr lParam){
creators[contactIndex].Y = (int) value;
break;
}
+
break;
}
}
+
creators.ForEach(creator => {
if(contacts.Count < contactCount && creator.TryCreate(out var contact)){
contacts.Add(contact);
@@ -230,6 +232,7 @@ public static TouchpadContact[] ParseInput(IntPtr lParam){
break;
}
}
+
Logger.Log(toLog);
return contacts.ToArray();
@@ -248,7 +251,7 @@ private static extern uint GetRawInputDeviceList(
uint cbSize);
[StructLayout(LayoutKind.Sequential)]
- private struct RAWINPUTDEVICELIST{
+ private struct RAWINPUTDEVICELIST {
public readonly IntPtr hDevice;
public readonly uint dwType; // RIM_TYPEMOUSE or RIM_TYPEKEYBOARD or RIM_TYPEHID
}
@@ -265,7 +268,7 @@ private static extern bool RegisterRawInputDevices(
uint cbSize);
[StructLayout(LayoutKind.Sequential)]
- private struct RAWINPUTDEVICE{
+ private struct RAWINPUTDEVICE {
public ushort usUsagePage;
public ushort usUsage;
public uint dwFlags; // RIDEV_INPUTSINK
@@ -285,13 +288,13 @@ private static extern uint GetRawInputData(
private const uint RID_INPUT = 0x10000003;
[StructLayout(LayoutKind.Sequential)]
- private struct RAWINPUT{
+ private struct RAWINPUT {
public readonly RAWINPUTHEADER Header;
public readonly RAWHID Hid;
}
[StructLayout(LayoutKind.Sequential)]
- private struct RAWINPUTHEADER{
+ private struct RAWINPUTHEADER {
public readonly uint dwType; // RIM_TYPEMOUSE or RIM_TYPEKEYBOARD or RIM_TYPEHID
public readonly uint dwSize;
public readonly IntPtr hDevice;
@@ -299,7 +302,7 @@ private struct RAWINPUTHEADER{
}
[StructLayout(LayoutKind.Sequential)]
- private struct RAWHID{
+ private struct RAWHID {
public readonly uint dwSizeHid;
public readonly uint dwCount;
public readonly IntPtr bRawData; // This is not for use.
@@ -323,14 +326,14 @@ private static extern uint GetRawInputDeviceInfo(
private const uint RIDI_DEVICEINFO = 0x2000000b;
[StructLayout(LayoutKind.Sequential)]
- private struct RID_DEVICE_INFO{
+ private struct RID_DEVICE_INFO {
public uint cbSize; // This is determined to accommodate RID_DEVICE_INFO_KEYBOARD.
public readonly uint dwType;
public readonly RID_DEVICE_INFO_HID hid;
}
[StructLayout(LayoutKind.Sequential)]
- private struct RID_DEVICE_INFO_HID{
+ private struct RID_DEVICE_INFO_HID {
public readonly uint dwVendorId;
public readonly uint dwProductId;
public readonly uint dwVersionNumber;
@@ -343,10 +346,32 @@ private static extern uint HidP_GetCaps(
IntPtr PreparsedData,
out HIDP_CAPS Capabilities);
+
+ [DllImport("hid.dll", SetLastError = true)]
+ private static extern uint HidP_GetButtonCaps(
+ HIDP_REPORT_TYPE reportType,
+ [Out] HIDP_BUTTON_CAPS[] buttonCaps,
+ ref ushort buttonCapsLength,
+ IntPtr preparsedData
+ );
+
+ [DllImport("hid.dll", SetLastError = true)]
+ private static extern uint HidP_GetUsages(
+ HIDP_REPORT_TYPE reportType,
+ ushort usagePage,
+ ushort linkCollection,
+ [Out] uint[] usageList,
+ ref uint usageLength,
+ IntPtr preparsedData,
+ byte[] report,
+ uint reportLength
+ );
+
+
private const uint HIDP_STATUS_SUCCESS = 0x00110000;
[StructLayout(LayoutKind.Sequential)]
- private struct HIDP_CAPS{
+ private struct HIDP_CAPS {
public readonly ushort Usage;
public readonly ushort UsagePage;
public readonly ushort InputReportByteLength;
@@ -375,14 +400,14 @@ private static extern uint HidP_GetValueCaps(
ref ushort ValueCapsLength,
IntPtr PreparsedData);
- private enum HIDP_REPORT_TYPE{
+ private enum HIDP_REPORT_TYPE {
HidP_Input,
HidP_Output,
HidP_Feature
}
[StructLayout(LayoutKind.Sequential)]
- private struct HIDP_VALUE_CAPS{
+ private struct HIDP_VALUE_CAPS {
public readonly ushort UsagePage;
public readonly byte ReportID;
@@ -450,3 +475,61 @@ private static extern uint HidP_GetUsageValue(
#endregion
}
+
+[StructLayout(LayoutKind.Sequential)]
+public struct HIDP_BUTTON_CAPS
+{
+ public ushort UsagePage;
+ public byte ReportID;
+ public bool IsAlias;
+
+ public ushort BitField;
+ public ushort LinkCollection;
+ public ushort LinkUsage;
+ public ushort LinkUsagePage;
+
+ public bool IsRange;
+ public bool IsStringRange;
+ public bool IsDesignatorRange;
+ public bool IsAbsolute;
+
+ [StructLayout(LayoutKind.Explicit)]
+ public struct RangeOrNotRange
+ {
+ [FieldOffset(0)]
+ public ushort UsageMin;
+ [FieldOffset(2)]
+ public ushort UsageMax;
+ [FieldOffset(4)]
+ public ushort StringMin;
+ [FieldOffset(6)]
+ public ushort StringMax;
+ [FieldOffset(8)]
+ public ushort DesignatorMin;
+ [FieldOffset(10)]
+ public ushort DesignatorMax;
+ [FieldOffset(12)]
+ public ushort DataIndexMin;
+ [FieldOffset(14)]
+ public ushort DataIndexMax;
+
+ [FieldOffset(0)]
+ public ushort Usage;
+ [FieldOffset(2)]
+ public ushort Reserved1;
+ [FieldOffset(4)]
+ public ushort StringIndex;
+ [FieldOffset(6)]
+ public ushort Reserved2;
+ [FieldOffset(8)]
+ public ushort DesignatorIndex;
+ [FieldOffset(10)]
+ public ushort Reserved3;
+ [FieldOffset(12)]
+ public ushort DataIndex;
+ [FieldOffset(14)]
+ public ushort Reserved4;
+ }
+
+ public RangeOrNotRange Range;
+}