From 539b44243f13ddb9299c293f6f2d230f2c74fea0 Mon Sep 17 00:00:00 2001 From: Bingxing Wang Date: Tue, 27 Aug 2019 21:46:46 -0700 Subject: [PATCH] Magic Trackpad 2: use standard Microsoft processing spec This is defined in https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/touchpad-windows-precision-touchpad-collection, and I slightly modified it for MT2. Should partially mitigate issue #212, #170, #166, #163, #161, #94, #38, #37 and #83. --- src/AmtPtpDeviceUsbUm/AmtPtpDeviceUsbUm.inf | Bin 8648 -> 8672 bytes src/AmtPtpDeviceUsbUm/Device.c | 59 ---- src/AmtPtpDeviceUsbUm/Device.h | 23 +- src/AmtPtpDeviceUsbUm/Driver.h | 1 - src/AmtPtpDeviceUsbUm/InputInterrupt.c | 330 ++++++++---------- src/AmtPtpDeviceUsbUm/InputStateMachine.c | 290 --------------- src/AmtPtpDeviceUsbUm/InputStateMachine.h | 68 ---- .../MagicTrackpad2PtpDevice.vcxproj | 2 - .../MagicTrackpad2PtpDevice.vcxproj.filters | 6 - 9 files changed, 155 insertions(+), 624 deletions(-) delete mode 100644 src/AmtPtpDeviceUsbUm/InputStateMachine.c delete mode 100644 src/AmtPtpDeviceUsbUm/InputStateMachine.h diff --git a/src/AmtPtpDeviceUsbUm/AmtPtpDeviceUsbUm.inf b/src/AmtPtpDeviceUsbUm/AmtPtpDeviceUsbUm.inf index 2649fce6ebb26153e7ac391016243cc81d02b841..7647e3f3e278c5fcd6a5a5ac8205ac965a45b3d6 100644 GIT binary patch delta 35 pcmX@%{J?pGjH0*#g9bw=Loq`tLlJ{6LoP!;Lkf_sIayk9EdZx>2$28) delta 11 ScmaFhe8PEyjN)Vy#WesQTm-NH diff --git a/src/AmtPtpDeviceUsbUm/Device.c b/src/AmtPtpDeviceUsbUm/Device.c index 27284dc..7672b74 100644 --- a/src/AmtPtpDeviceUsbUm/Device.c +++ b/src/AmtPtpDeviceUsbUm/Device.c @@ -117,7 +117,6 @@ AmtPtpCreateDevice( return status; } -_IRQL_requires_(PASSIVE_LEVEL) NTSTATUS AmtPtpEvtDevicePrepareHardware( _In_ WDFDEVICE Device, @@ -189,61 +188,6 @@ AmtPtpEvtDevicePrepareHardware( ); return status; } - - // Set fuzz information - pDeviceContext->HorizonalFuzz = pDeviceContext->DeviceInfo->x.snratio ? - (pDeviceContext->DeviceInfo->x.max - pDeviceContext->DeviceInfo->x.min) / pDeviceContext->DeviceInfo->x.snratio : - 0.0; - - pDeviceContext->VerticalFuzz = pDeviceContext->DeviceInfo->y.snratio ? - (pDeviceContext->DeviceInfo->y.max - pDeviceContext->DeviceInfo->y.min) / pDeviceContext->DeviceInfo->y.snratio : - 0.0; - - pDeviceContext->PressureFuzz = pDeviceContext->DeviceInfo->p.snratio ? - (pDeviceContext->DeviceInfo->p.max - pDeviceContext->DeviceInfo->p.min) / pDeviceContext->DeviceInfo->p.snratio : - 0.0; - - pDeviceContext->WidthFuzz = pDeviceContext->DeviceInfo->w.snratio ? - (pDeviceContext->DeviceInfo->w.max - pDeviceContext->DeviceInfo->w.min) / pDeviceContext->DeviceInfo->w.snratio : - 0.0; - - pDeviceContext->OrientationFuzz = pDeviceContext->DeviceInfo->o.snratio ? - (pDeviceContext->DeviceInfo->o.max - pDeviceContext->DeviceInfo->o.min) / pDeviceContext->DeviceInfo->o.snratio : - 0.0; - - pDeviceContext->SgContactSizeQualLevel = SIZE_QUALIFICATION_THRESHOLD; - pDeviceContext->MuContactSizeQualLevel = SIZE_MU_LOWER_THRESHOLD; - pDeviceContext->PressureQualLevel = PRESSURE_QUALIFICATION_THRESHOLD; - - pDeviceContext->TouchStateMachineInfo.HorizonalFuzz = pDeviceContext->HorizonalFuzz; - pDeviceContext->TouchStateMachineInfo.VerticalFuzz = pDeviceContext->VerticalFuzz; - pDeviceContext->TouchStateMachineInfo.WidthFuzz = pDeviceContext->WidthFuzz; - pDeviceContext->TouchStateMachineInfo.OrientationFuzz = pDeviceContext->OrientationFuzz; - pDeviceContext->TouchStateMachineInfo.PressureFuzz = pDeviceContext->PressureFuzz; - - status = SmResetState(&pDeviceContext->TouchStateMachineInfo); - if (!NT_SUCCESS(status)) { - - TraceEvents( - TRACE_LEVEL_ERROR, - TRACE_DEVICE, - "%!FUNC! SmResetState failed with %!STATUS!", - status - ); - return status; - - } - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DEVICE, - "%!FUNC! fuzz information: h = %f, v = %f, p = %f, w = %f, o = %f", - pDeviceContext->HorizonalFuzz, - pDeviceContext->VerticalFuzz, - pDeviceContext->PressureFuzz, - pDeviceContext->WidthFuzz, - pDeviceContext->OrientationFuzz - ); } // @@ -551,8 +495,6 @@ AmtPtpSetWellspringMode( } -// D0 Entry & Exit -_IRQL_requires_(PASSIVE_LEVEL) NTSTATUS AmtPtpEvtDeviceD0Entry( _In_ WDFDEVICE Device, @@ -642,7 +584,6 @@ AmtPtpEvtDeviceD0Entry( return status; } -_IRQL_requires_(PASSIVE_LEVEL) NTSTATUS AmtPtpEvtDeviceD0Exit( _In_ WDFDEVICE Device, diff --git a/src/AmtPtpDeviceUsbUm/Device.h b/src/AmtPtpDeviceUsbUm/Device.h index 837ee72..e9abca4 100644 --- a/src/AmtPtpDeviceUsbUm/Device.h +++ b/src/AmtPtpDeviceUsbUm/Device.h @@ -24,14 +24,7 @@ typedef struct _DEVICE_CONTEXT BOOL IsSurfaceReportOn; BOOL IsButtonReportOn; - double HorizonalFuzz; - double VerticalFuzz; - double PressureFuzz; - double WidthFuzz; - double OrientationFuzz; - PTP_CONTACT_RAW ContactRepository[5]; - SM_RUNTIME_INFORMATION TouchStateMachineInfo; LARGE_INTEGER PerfCounter; @@ -63,6 +56,8 @@ AmtPtpCreateDevice( // handle // EVT_WDF_DEVICE_PREPARE_HARDWARE AmtPtpEvtDevicePrepareHardware; +EVT_WDF_DEVICE_D0_ENTRY AmtPtpEvtDeviceD0Entry; +EVT_WDF_DEVICE_D0_EXIT AmtPtpEvtDeviceD0Exit; _IRQL_requires_(PASSIVE_LEVEL) NTSTATUS @@ -96,20 +91,6 @@ DbgDevicePowerString( _In_ WDF_POWER_DEVICE_STATE Type ); -_IRQL_requires_(PASSIVE_LEVEL) -NTSTATUS -AmtPtpEvtDeviceD0Entry( - _In_ WDFDEVICE Device, - _In_ WDF_POWER_DEVICE_STATE PreviousState -); - -_IRQL_requires_(PASSIVE_LEVEL) -NTSTATUS -AmtPtpEvtDeviceD0Exit( - _In_ WDFDEVICE Device, - _In_ WDF_POWER_DEVICE_STATE TargetState -); - _IRQL_requires_(PASSIVE_LEVEL) VOID AmtPtpEvtUsbInterruptPipeReadComplete( diff --git a/src/AmtPtpDeviceUsbUm/Driver.h b/src/AmtPtpDeviceUsbUm/Driver.h index 8500049..d0340f4 100644 --- a/src/AmtPtpDeviceUsbUm/Driver.h +++ b/src/AmtPtpDeviceUsbUm/Driver.h @@ -14,7 +14,6 @@ #include "AppleDefinition.h" #include "Hid.h" -#include "InputStateMachine.h" #include "Device.h" #include "Queue.h" diff --git a/src/AmtPtpDeviceUsbUm/InputInterrupt.c b/src/AmtPtpDeviceUsbUm/InputInterrupt.c index 50fa980..b5100b8 100644 --- a/src/AmtPtpDeviceUsbUm/InputInterrupt.c +++ b/src/AmtPtpDeviceUsbUm/InputInterrupt.c @@ -92,7 +92,7 @@ AmtPtpEvtUsbInterruptPipeReadComplete( WDFDEVICE device; PDEVICE_CONTEXT pDeviceContext = Context; - UCHAR* szBuffer = NULL; + UCHAR* pBuffer = NULL; NTSTATUS status; TraceEvents( @@ -142,68 +142,64 @@ AmtPtpEvtUsbInterruptPipeReadComplete( // Dispatch USB Interrupt routine by device family switch (pDeviceContext->DeviceInfo->tp_type) { - case TYPE1: - // case TYPE4: - { + case TYPE1: + { + TraceEvents( + TRACE_LEVEL_WARNING, + TRACE_DRIVER, + "%!FUNC! Mode not yet supported" + ); + break; + } + // Universal routine handler + case TYPE2: + case TYPE3: + case TYPE4: + { + pBuffer = WdfMemoryGetBuffer( + Buffer, + NULL + ); + + status = AmtPtpServiceTouchInputInterrupt( + pDeviceContext, + pBuffer, + NumBytesTransferred + ); + + if (!NT_SUCCESS(status)) { TraceEvents( TRACE_LEVEL_WARNING, TRACE_DRIVER, - "%!FUNC! Mode not yet supported" + "%!FUNC! AmtPtpServiceTouchInputInterrupt failed with %!STATUS!", + status ); - break; - } - // Universal routine handler - case TYPE2: - case TYPE3: - case TYPE4: - { - - szBuffer = WdfMemoryGetBuffer( - Buffer, - NULL - ); - status = AmtPtpServiceTouchInputInterrupt( - pDeviceContext, - szBuffer, - NumBytesTransferred - ); - - if (!NT_SUCCESS(status)) { - TraceEvents( - TRACE_LEVEL_WARNING, - TRACE_DRIVER, - "%!FUNC! AmtPtpServiceTouchInputInterrupt failed with %!STATUS!", - status - ); - } - break; - } - // Magic Trackpad 2 - case TYPE5: - { + break; + } + // Magic Trackpad 2 + case TYPE5: + { + pBuffer = WdfMemoryGetBuffer( + Buffer, + NULL + ); + status = AmtPtpServiceTouchInputInterruptType5( + pDeviceContext, + pBuffer, + NumBytesTransferred + ); - szBuffer = WdfMemoryGetBuffer( - Buffer, - NULL - ); - status = AmtPtpServiceTouchInputInterruptType5( - pDeviceContext, - szBuffer, - NumBytesTransferred + if (!NT_SUCCESS(status)) { + TraceEvents( + TRACE_LEVEL_WARNING, + TRACE_DRIVER, + "%!FUNC! AmtPtpServiceTouchInputInterrupt5 failed with %!STATUS!", + status ); - - if (!NT_SUCCESS(status)) { - TraceEvents( - TRACE_LEVEL_WARNING, - TRACE_DRIVER, - "%!FUNC! AmtPtpServiceTouchInputInterrupt5 failed with %!STATUS!", - status - ); - } - break; - } + break; + } } TraceEvents( @@ -222,9 +218,7 @@ AmtPtpEvtUsbInterruptReadersFailed( _In_ USBD_STATUS UsbdStatus ) { - WDFDEVICE device = WdfIoTargetGetDevice(WdfUsbTargetPipeGetIoTarget(Pipe)); - - UNREFERENCED_PARAMETER(device); + UNREFERENCED_PARAMETER(Pipe); UNREFERENCED_PARAMETER(UsbdStatus); UNREFERENCED_PARAMETER(Status); @@ -239,10 +233,9 @@ AmtPtpServiceTouchInputInterrupt( _In_ size_t NumBytesTransferred ) { - NTSTATUS Status; WDFREQUEST Request; - WDFMEMORY reqMemory; + WDFMEMORY RequestMemory; PTP_REPORT PtpReport; LARGE_INTEGER CurrentPerfCounter; LONGLONG PerfCounterDelta; @@ -260,21 +253,8 @@ AmtPtpServiceTouchInputInterrupt( size_t fingerprintSize = (unsigned int) DeviceContext->DeviceInfo->tp_fsize; USHORT x = 0, y = 0; - QueryPerformanceCounter( - &CurrentPerfCounter - ); - - // Scan time is in 100us - PerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100; - // Only two bytes allocated - if (PerfCounterDelta > 0xFF) - { - PerfCounterDelta = 0xFF; - } - Status = STATUS_SUCCESS; PtpReport.ReportID = REPORTID_MULTITOUCH; - PtpReport.ScanTime = (USHORT) PerfCounterDelta; PtpReport.IsButtonClicked = 0; // Retrieve next PTP touchpad request. @@ -292,10 +272,24 @@ AmtPtpServiceTouchInputInterrupt( goto exit; } + QueryPerformanceCounter( + &CurrentPerfCounter + ); + + // Scan time is in 100us + PerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100; + // Only two bytes allocated + if (PerfCounterDelta > 0xFF) + { + PerfCounterDelta = 0xFF; + } + + PtpReport.ScanTime = (USHORT) PerfCounterDelta; + // Allocate output memory. Status = WdfRequestRetrieveOutputMemory( Request, - &reqMemory + &RequestMemory ); if (!NT_SUCCESS(Status)) { @@ -315,12 +309,14 @@ AmtPtpServiceTouchInputInterrupt( if (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS; PtpReport.ContactCount = (UCHAR) raw_n; +#ifdef INPUT_CONTENT_TRACE TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! with %llu points.", raw_n ); +#endif // Fingers for (i = 0; i < raw_n; i++) { @@ -329,8 +325,10 @@ AmtPtpServiceTouchInputInterrupt( f = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize); // Translate X and Y - x = (AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min) > 0 ? ((USHORT)(AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min)) : 0; - y = (DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y)) > 0 ? ((USHORT)(DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y))) : 0; + x = (AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min) > 0 ? + ((USHORT)(AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min)) : 0; + y = (DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y)) > 0 ? + ((USHORT)(DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y))) : 0; // Defuzz functions remain the same // TODO: Implement defuzz later @@ -340,6 +338,7 @@ AmtPtpServiceTouchInputInterrupt( PtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f->touch_major) << 1) >= 200; PtpReport.Contacts[i].Confidence = (AmtRawToInteger(f->touch_minor) << 1) > 0; +#ifdef INPUT_CONTENT_TRACE TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_INPUT, @@ -354,7 +353,7 @@ AmtPtpServiceTouchInputInterrupt( AmtRawToInteger(f->origin), (UCHAR) i ); - +#endif } } @@ -363,17 +362,12 @@ AmtPtpServiceTouchInputInterrupt( // Handles trackpad button input here. if (Buffer[DeviceContext->DeviceInfo->tp_button]) { PtpReport.IsButtonClicked = TRUE; - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC!: Trackpad button clicked" - ); } } // Compose final report and write it back Status = WdfMemoryCopyFromBuffer( - reqMemory, + RequestMemory, 0, (PVOID) &PtpReport, sizeof(PTP_REPORT) @@ -420,10 +414,12 @@ AmtPtpServiceTouchInputInterruptType5( ) { - NTSTATUS status; - WDFREQUEST request; - WDFMEMORY reqMemory; - PTP_REPORT report; + NTSTATUS Status; + WDFREQUEST Request; + WDFMEMORY RequestMemory; + PTP_REPORT PtpReport; + LARGE_INTEGER CurrentPerfCounter; + LONGLONG PerfCounterDelta; const struct TRACKPAD_FINGER *f; const struct TRACKPAD_FINGER_TYPE5 *f_type5; @@ -434,19 +430,21 @@ AmtPtpServiceTouchInputInterruptType5( "%!FUNC! Entry" ); - status = STATUS_SUCCESS; - INT x, y = 0; + Status = STATUS_SUCCESS; + PtpReport.ReportID = REPORTID_MULTITOUCH; + PtpReport.IsButtonClicked = 0; + INT x, y = 0; size_t raw_n, i = 0; size_t headerSize = (unsigned int) DeviceContext->DeviceInfo->tp_header; size_t fingerprintSize = (unsigned int) DeviceContext->DeviceInfo->tp_fsize; - status = WdfIoQueueRetrieveNextRequest( + Status = WdfIoQueueRetrieveNextRequest( DeviceContext->InputQueue, - &request + &Request ); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(Status)) { TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_DRIVER, @@ -455,35 +453,48 @@ AmtPtpServiceTouchInputInterruptType5( goto exit; } - status = WdfRequestRetrieveOutputMemory( - request, - &reqMemory + Status = WdfRequestRetrieveOutputMemory( + Request, + &RequestMemory ); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(Status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!", - status + Status ); goto exit; } - // First things - report.ReportID = REPORTID_MULTITOUCH; - // 60Hz in 100us unit - report.ScanTime = 167; - report.IsButtonClicked = 0; + QueryPerformanceCounter( + &CurrentPerfCounter + ); - // Check things to report - if (DeviceContext->IsSurfaceReportOn) { + // Scan time is in 100us + PerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100; + // Only two bytes allocated + if (PerfCounterDelta > 0xFF) + { + PerfCounterDelta = 0xFF; + } - SM_PROJECTED_INFORMATION projInfo; - PTP_CONTACT_RAW rawPointers[MT2_MAX_SLOT]; + PtpReport.ScanTime = (USHORT) PerfCounterDelta; - // Iterations to read + // Type 5 finger report + if (DeviceContext->IsSurfaceReportOn) { raw_n = (NumBytesTransferred - headerSize) / fingerprintSize; if (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS; + PtpReport.ContactCount = (UCHAR)raw_n; + +#ifdef INPUT_CONTENT_TRACE + TraceEvents( + TRACE_LEVEL_INFORMATION, + TRACE_DRIVER, + "%!FUNC! with %llu points.", + raw_n + ); +#endif // Fingers to array for (i = 0; i < raw_n; i++) { @@ -498,109 +509,74 @@ AmtPtpServiceTouchInputInterruptType5( x = (SHORT) (tmp_x << 3) >> 3; y = -(INT) (tmp_y << 6) >> 19; - // Set for state machine's reference - rawPointers[i].ContactId = f_type5->ContactIdentifier.Id; - rawPointers[i].X = (USHORT) (x - DeviceContext->DeviceInfo->x.min); - rawPointers[i].Y = (USHORT) (y - DeviceContext->DeviceInfo->y.min); - rawPointers[i].Size = f_type5->Size; - rawPointers[i].TouchMajor = (USHORT) (AmtRawToInteger(f_type5->TouchMajor) << 1); - rawPointers[i].TouchMinor = (USHORT) (AmtRawToInteger(f_type5->TouchMinor) << 1); - rawPointers[i].State = CONTACT_NEW; - - } - - // State machine - status = SmHandleInputRoutine( - rawPointers, - (int) raw_n, - &DeviceContext->TouchStateMachineInfo); - - if (!NT_SUCCESS(status)) { - TraceEvents( - TRACE_LEVEL_ERROR, - TRACE_DRIVER, - "%!FUNC! SmHandleInputRoutine failed with %!STATUS!", - status - ); - goto exit; - } - - // Retrieve result - SmGetPtpReportSlots( - &DeviceContext->TouchStateMachineInfo, - &projInfo - ); - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC!: SmGetPtpReportSlots returned %d contact(s).", - projInfo.ReportedContactsCount - ); - - // Set & trace contact - for (i = 0; i < projInfo.ReportedContactsCount; i++) { - - report.Contacts[i] = projInfo.Contacts[i]; + x = (x - DeviceContext->DeviceInfo->x.min) > 0 ? (x - DeviceContext->DeviceInfo->x.min) : 0; + y = (y - DeviceContext->DeviceInfo->y.min) > 0 ? (y - DeviceContext->DeviceInfo->y.min) : 0; + // Set for state machine's reference + PtpReport.Contacts[i].ContactID = f_type5->ContactIdentifier.Id; + PtpReport.Contacts[i].X = (USHORT) x; + PtpReport.Contacts[i].Y = (USHORT) y; + PtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f_type5->TouchMajor) << 1) > 0; + + // The Microsoft spec says reject any input larger than 25mm. This is not ideal + // for Magic Trackpad 2 - so we raised the threshold a bit higher. + // Or maybe I used the wrong unit? IDK + PtpReport.Contacts[i].Confidence = (AmtRawToInteger(f_type5->TouchMinor) << 1) < 345 && + (AmtRawToInteger(f_type5->TouchMinor) << 1) < 345; + +#ifdef INPUT_CONTENT_TRACE TraceEvents( TRACE_LEVEL_INFORMATION, TRACE_INPUT, - "%!FUNC!: PTP Origin = %d, X = %d, Y = %d, TipSwitch = %d, Confidence = %d", - report.Contacts[i].ContactID, - report.Contacts[i].X, - report.Contacts[i].Y, - report.Contacts[i].TipSwitch, - report.Contacts[i].Confidence + "%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, origin = %d", + i, + PtpReport.Contacts[i].X, + PtpReport.Contacts[i].Y, + PtpReport.Contacts[i].TipSwitch, + PtpReport.Contacts[i].Confidence, + AmtRawToInteger(f_type5->TouchMajor) << 1, + AmtRawToInteger(f_type5->TouchMinor) << 1, + f_type5->ContactIdentifier.Id ); - +#endif } - - // Set count - report.ContactCount = projInfo.ReportedContactsCount; - } // Button if (DeviceContext->IsButtonReportOn) { if (Buffer[DeviceContext->DeviceInfo->tp_button]) { - report.IsButtonClicked = TRUE; - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC!: Trackpad button clicked" - ); + PtpReport.IsButtonClicked = TRUE; } } // Write output - status = WdfMemoryCopyFromBuffer( - reqMemory, + Status = WdfMemoryCopyFromBuffer( + RequestMemory, 0, - (PVOID) &report, + (PVOID) &PtpReport, sizeof(PTP_REPORT) ); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(Status)) { TraceEvents( TRACE_LEVEL_ERROR, TRACE_DRIVER, "%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!", - status + Status ); goto exit; } // Set result WdfRequestSetInformation( - request, + Request, sizeof(PTP_REPORT) ); // Set completion flag WdfRequestComplete( - request, - status + Request, + Status ); exit: @@ -609,7 +585,7 @@ AmtPtpServiceTouchInputInterruptType5( TRACE_DRIVER, "%!FUNC! Exit" ); - return status; + return Status; } diff --git a/src/AmtPtpDeviceUsbUm/InputStateMachine.c b/src/AmtPtpDeviceUsbUm/InputStateMachine.c deleted file mode 100644 index a31a625..0000000 --- a/src/AmtPtpDeviceUsbUm/InputStateMachine.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "Driver.h" -#include "InputStateMachine.tmh" - -_IRQL_requires_(PASSIVE_LEVEL) -HRESULT SmHandleInputRoutine( - _In_ PTP_CONTACT_RAW pointers[MT2_MAX_SLOT], - _In_ INT actualPointers, - _In_ PSM_RUNTIME_INFORMATION pState) -{ - - HRESULT status = S_OK; - BOOLEAN found = FALSE; - - int preProcessCounter = 0; - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Entry" - ); - - // Check pointer - if (pState == NULL) { - - TraceEvents( - TRACE_LEVEL_WARNING, - TRACE_INPUT, - "%!FUNC! Invalid pointer address (argument)" - ); - - status = STATUS_INVALID_PARAMETER; - goto exit; - - } - - // Verify if contact points are found in registry. - for (int i = 0; i < actualPointers; i++) - { - switch (pState->Contacts[pointers[i].ContactId].State) - { - case CONTACT_NEW: - case CONTACT_CONTINUED: - case CONTACT_CONFIDENCE_CANCELLED: - // We don't need to continue searching. Set pivot to null - found = TRUE; - break; - case CONTACT_INVALID: - break; - } - - // Exit if flag is set - if (found) break; - } - - // If all contact points are not found in registry, reset state machine. - if (!found) { - status = SmResetState(pState); - if (!NT_SUCCESS(status)) goto exit; - pState->State = STATE_NEW_SESSION; - } - else { - pState->State = STATE_CONTINUED_SESSION; - } - - // Set information to registry. - for (int i = 0; i < actualPointers; i++) - { - - UCHAR contactId = pointers[i].ContactId; - - switch (pState->Contacts[contactId].State) - { - case CONTACT_NEW: - case CONTACT_CONTINUED: - // Input defuzz - pState->Contacts[contactId].X = (USHORT) SmDefuzzInput( - pointers[i].X, - pState->Contacts[contactId].X, - pState->HorizonalFuzz - ); - pState->Contacts[contactId].Y = (USHORT) SmDefuzzInput( - pointers[i].Y, - pState->Contacts[contactId].Y, - pState->VerticalFuzz - ); - // Non-fuzzing values - pState->Contacts[contactId].TouchMajor = pointers[i].TouchMajor; - pState->Contacts[contactId].TouchMinor = pointers[i].TouchMinor; - // Check touch major size - pState->Contacts[contactId].State = - (pointers[i].TouchMajor >= MT2_PALM_REJECTION_CONTACT_THRESHOLD) ? - CONTACT_CONFIDENCE_CANCELLED : CONTACT_CONTINUED; - break; - case CONTACT_INVALID: - pState->Contacts[contactId].State = CONTACT_NEW; - pState->Contacts[contactId].ContactId = contactId; - pState->Contacts[contactId].X = pointers[i].X; - pState->Contacts[contactId].Y = pointers[i].Y; - pState->Contacts[contactId].TouchMajor = pointers[i].TouchMajor; - pState->Contacts[contactId].TouchMinor = pointers[i].TouchMinor; - // Assign content - break; - case CONTACT_CONFIDENCE_CANCELLED: - // State doesn't change. Defuzz input, still have confidence cancelled. - // Input defuzz - pState->Contacts[contactId].X = (USHORT) SmDefuzzInput( - pointers[i].X, - pState->Contacts[contactId].X, - pState->HorizonalFuzz - ); - pState->Contacts[contactId].Y = (USHORT) SmDefuzzInput( - pointers[i].Y, - pState->Contacts[contactId].Y, - pState->VerticalFuzz - ); - // Non-fuzzing values - pState->Contacts[contactId].TouchMajor = pointers[i].TouchMajor; - pState->Contacts[contactId].TouchMinor = pointers[i].TouchMinor; - break; - } - - preProcessCounter++; - - } - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC! Pre processed %d contact(s).", - preProcessCounter - ); - -exit: - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Exit" - ); - - return status; - -} - -_IRQL_requires_(PASSIVE_LEVEL) -VOID SmGetPtpReportSlots( - _In_ PSM_RUNTIME_INFORMATION pState, - _In_ PSM_PROJECTED_INFORMATION pProjectedInformation -) -{ - - UCHAR contactCount = 0; - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Entry" - ); - - if (pState == NULL) { - - TraceEvents( - TRACE_LEVEL_WARNING, - TRACE_INPUT, - "%!FUNC! Invalid pointer address (argument)" - ); - - goto exit; - - } - - for (UCHAR i = 0; i < MT2_MAX_SLOT; i++) { - - if (pState->Contacts[i].State != CONTACT_INVALID) { - - pProjectedInformation->Contacts[contactCount].ContactID = i; - pProjectedInformation->Contacts[contactCount].X = pState->Contacts[i].X; - pProjectedInformation->Contacts[contactCount].Y = pState->Contacts[i].Y; - pProjectedInformation->Contacts[contactCount].Confidence = (pState->Contacts[i].State == CONTACT_CONFIDENCE_CANCELLED) ? 0 : 1; - pProjectedInformation->Contacts[contactCount].TipSwitch = pState->Contacts[i].TouchMajor >= MT2_TIP_SWITCH_THRESHOLD; - - contactCount++; - - } - - if (contactCount == 5) { - // We have 5 contacts to report. Stop. Discard rest - break; - } - - } - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC! Post processed %d points.", - contactCount - ); - - pProjectedInformation->ReportedContactsCount = contactCount; - -exit: - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Exit" - ); - -} - -_IRQL_requires_(PASSIVE_LEVEL) -HRESULT SmResetState( - _In_ PSM_RUNTIME_INFORMATION pState -) -{ - - HRESULT status = S_OK; - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Entry" - ); - - if (pState == NULL) { - // Invalid parameter - status = STATUS_INVALID_PARAMETER; - goto exit; - } - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_INPUT, - "%!FUNC! Resetting input session" - ); - - // Reset state - pState->State = STATE_NEW_SESSION; - - // Reset all points & contact points - for (int i = 0; i < MT2_MAX_SLOT; i++) { - - pState->Contacts[i].X = 0; - pState->Contacts[i].Y = 0; - pState->Contacts[i].Size = 0; - pState->Contacts[i].Pressure = 0; - pState->Contacts[i].TouchMajor = 0; - pState->Contacts[i].TouchMinor = 0; - pState->Contacts[i].Orientation = 0; - pState->Contacts[i].State = CONTACT_INVALID; - pState->Contacts[i].ContactId = INVALID_ORIGIN_ID; - - } - -exit: - - TraceEvents( - TRACE_LEVEL_INFORMATION, - TRACE_DRIVER, - "%!FUNC! Exit" - ); - - return status; - -} - -// Debuzz function from Linux Kernel: drivers/input/input.c -_IRQL_requires_(PASSIVE_LEVEL) -static INT SmDefuzzInput( - _In_ int NewValue, - _In_ int OldValue, - _In_ double Fuzz -) -{ - - if (Fuzz) { - if (NewValue > OldValue - Fuzz / 2 && NewValue < OldValue + Fuzz / 2) - return OldValue; - - if (NewValue > OldValue - Fuzz && NewValue < OldValue + Fuzz) - return (OldValue * 3 + NewValue) / 4; - - if (NewValue > OldValue - Fuzz * 2 && NewValue < OldValue + Fuzz * 2) - return (OldValue + NewValue) / 2; - } - - return NewValue; - -} diff --git a/src/AmtPtpDeviceUsbUm/InputStateMachine.h b/src/AmtPtpDeviceUsbUm/InputStateMachine.h deleted file mode 100644 index 459fecc..0000000 --- a/src/AmtPtpDeviceUsbUm/InputStateMachine.h +++ /dev/null @@ -1,68 +0,0 @@ -// InputStateMachine.h: Input data post-process routines. - -#pragma once - -enum TOUCH_SESSION_STATE { - STATE_NEW_SESSION = 0, - STATE_CONTINUED_SESSION = 1 -}; - -// This will never be a valid origin ID on Magic Trackpad 2 -#define INVALID_ORIGIN_ID 255 -#define MT2_MAX_SLOT 16 - -#define MT2_TIP_SWITCH_THRESHOLD 100 -#define MT2_PALM_REJECTION_CONTACT_THRESHOLD 350 - -typedef struct _SM_RUNTIME_INFORMATION { - - // Assign 16 input slots, as this is the max value that Contact ID can report. - // And this enables O(1) searching - PTP_CONTACT_RAW Contacts[MT2_MAX_SLOT]; - - double LowerBoundary; - double UpperBoundary; - - // Some fuzz information will be recorded, - // however not used at this moment. - - double HorizonalFuzz; - double VerticalFuzz; - double PressureFuzz; - double WidthFuzz; - double OrientationFuzz; - enum TOUCH_SESSION_STATE State; - -} SM_RUNTIME_INFORMATION, *PSM_RUNTIME_INFORMATION; - -typedef struct _SM_PROJECTED_INFORMATION { - - PTP_CONTACT Contacts[PTP_MAX_CONTACT_POINTS]; - UCHAR ReportedContactsCount; - -} SM_PROJECTED_INFORMATION, *PSM_PROJECTED_INFORMATION; - -_IRQL_requires_(PASSIVE_LEVEL) -HRESULT SmHandleInputRoutine( - _In_ PTP_CONTACT_RAW pointers[MT2_MAX_SLOT], - _In_ INT actualPointers, - _In_ PSM_RUNTIME_INFORMATION pState -); - -_IRQL_requires_(PASSIVE_LEVEL) -HRESULT SmResetState( - _In_ PSM_RUNTIME_INFORMATION pState -); - -_IRQL_requires_(PASSIVE_LEVEL) -VOID SmGetPtpReportSlots( - _In_ PSM_RUNTIME_INFORMATION pState, - _In_ PSM_PROJECTED_INFORMATION pProjectedInformation -); - -_IRQL_requires_(PASSIVE_LEVEL) -static INT SmDefuzzInput( - _In_ int NewValue, - _In_ int OldValue, - _In_ double Fuzz -); diff --git a/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj b/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj index ddaa2f9..713e222 100644 --- a/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj +++ b/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj @@ -43,7 +43,6 @@ - @@ -56,7 +55,6 @@ - diff --git a/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters b/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters index ffcea5d..e261f92 100644 --- a/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters +++ b/src/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters @@ -58,9 +58,6 @@ Device Specific Metadata Files - - Header Files - Header Files @@ -81,9 +78,6 @@ Source Files - - Source Files -