From 40de4e2b0fc87d6aa2167c130c0f9829ab475fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Grennerat?= Date: Mon, 22 Jul 2024 18:52:09 +0200 Subject: [PATCH] RawInputs parsing: supporting sequential contacts trying to fix #63, #61, #44 and #39 --- .../threefingerdrag/ThreeFingerDrag.cs | 3 +- .../touchpad/TouchpadHelper.cs | 126 ++++++++++-------- .../utils/TouchpadContact.cs | 2 +- 3 files changed, 77 insertions(+), 54 deletions(-) diff --git a/ThreeFingerDragOnWindows/threefingerdrag/ThreeFingerDrag.cs b/ThreeFingerDragOnWindows/threefingerdrag/ThreeFingerDrag.cs index 2faf8bb..173f3e1 100644 --- a/ThreeFingerDragOnWindows/threefingerdrag/ThreeFingerDrag.cs +++ b/ThreeFingerDragOnWindows/threefingerdrag/ThreeFingerDrag.cs @@ -25,7 +25,6 @@ public ThreeFingerDrag(){ public void OnTouchpadContact(TouchpadContact[] oldContacts, TouchpadContact[] contacts, long elapsed){ bool hasFingersReleased = elapsed > RELEASE_FINGERS_THRESHOLD_MS; - Logger.Log(""); Logger.Log("TFD: " + string.Join(", ", oldContacts.Select(c => c.ToString())) + " | " + string.Join(", ", contacts.Select(c => c.ToString())) + " | " + elapsed); bool areContactsIdsCommons = FingerCounter.AreContactsIdsCommons(oldContacts, contacts); @@ -78,11 +77,13 @@ public void OnTouchpadContact(TouchpadContact[] oldContacts, TouchpadContact[] c _dragEndTimer.Start(); } } + Logger.Log(""); } private void OnTimerElapsed(object source, ElapsedEventArgs e){ if(_isDragging){ Logger.Log(" STOP DRAG FROM TIMER, Left click up"); + Logger.Log(""); StopDrag(); } } diff --git a/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs b/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs index d590891..7cb5f50 100644 --- a/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs +++ b/ThreeFingerDragOnWindows/touchpad/TouchpadHelper.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using ThreeFingerDragEngine.utils; @@ -151,64 +152,85 @@ public static TouchpadContact[] ParseInput(IntPtr lParam){ return null; uint scanTime = 0; - uint contactCount = 0; - TouchpadContactCreator creator = new(); + uint contactCount = 99; + + List creators = new(); List contacts = new(); + // Iterating though each value (scanTime, contactCount, contactId, x, y) + // Sometimes, iterates also through contacts by looping these values for each contact + String toLog = "Parsing RawInput: "; foreach(var valueCap in valueCaps.OrderBy(x => x.LinkCollection)){ - if(HidP_GetUsageValue( - HIDP_REPORT_TYPE.HidP_Input, - valueCap.UsagePage, - valueCap.LinkCollection, - valueCap.Usage, - out var value, - preparsedDataPointer, - rawHidRawDataPointer, - (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){ - case 0: - switch (valueCap.UsagePage, valueCap.Usage){ - case (0x0D, 0x56): // Scan Time - scanTime = value; - break; - - case (0x0D, 0x54): // Contact Count - contactCount = value; - break; - } - - break; - - default: - switch (valueCap.UsagePage, valueCap.Usage){ - case (0x0D, 0x51): // Contact ID - creator.ContactId = (int)value; - break; - - case (0x01, 0x30): // X - creator.X = (int)value; - break; - - case (0x01, 0x31): // Y - creator.Y = (int)value; - break; - } - - break; + toLog += "| "; + // 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)); + + 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) + 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){ + case 0: + switch (valueCap.UsagePage, valueCap.Usage){ + case (0x0D, 0x56): // Scan Time + toLog += $"sT{value} "; + scanTime = value; + break; + + case (0x0D, 0x54): // Contact Count + toLog += $"cC{value} "; + contactCount = value; + break; + } + + break; + + default: + while(creators.Count <= contactIndex){ + creators.Add(new TouchpadContactCreator()); + } + + switch (valueCap.UsagePage, valueCap.Usage){ + case (0x0D, 0x51): // Contact ID + toLog += $"ID{(int) value} "; + creators[contactIndex].ContactId = (int) value; + break; + + case (0x01, 0x30): // X + toLog += "X "; + creators[contactIndex].X = (int) value; + break; + + case (0x01, 0x31): // Y + toLog += "Y "; + creators[contactIndex].Y = (int) value; + break; + } + break; + } } - - if(creator.TryCreate(out var contact)){ - contacts.Add(contact); - if(contacts.Count >= contactCount) - break; - - creator.Clear(); + creators.ForEach(creator => { + if(contacts.Count < contactCount && creator.TryCreate(out var contact)){ + contacts.Add(contact); + creator.Clear(); + } + }); + if(contacts.Count >= contactCount){ + break; } } + Logger.Log(toLog); return contacts.ToArray(); } finally{ diff --git a/ThreeFingerDragOnWindows/utils/TouchpadContact.cs b/ThreeFingerDragOnWindows/utils/TouchpadContact.cs index b9ea477..f7a3d0f 100644 --- a/ThreeFingerDragOnWindows/utils/TouchpadContact.cs +++ b/ThreeFingerDragOnWindows/utils/TouchpadContact.cs @@ -62,4 +62,4 @@ public void Clear(){ X = null; Y = null; } -} \ No newline at end of file +}