Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MT2 Improvements #533

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 33 additions & 43 deletions src/AmtPtpDeviceUsbUm/InputInterrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -418,11 +418,10 @@ AmtPtpServiceTouchInputInterruptType5(
WDFREQUEST Request;
WDFMEMORY RequestMemory;
PTP_REPORT PtpReport;
LARGE_INTEGER CurrentPerfCounter;
LONGLONG PerfCounterDelta;

const struct TRACKPAD_FINGER *f;
const struct TRACKPAD_FINGER_TYPE5 *f_type5;
const struct TRACKPAD_FINGER_TYPE5* f;
const struct TRACKPAD_REPORT_TYPE5* mt_report;
const struct TRACKPAD_COMBINED_REPORT_TYPE5* full_report;

TraceEvents(
TRACE_LEVEL_INFORMATION,
Expand All @@ -434,10 +433,9 @@ AmtPtpServiceTouchInputInterruptType5(
PtpReport.ReportID = REPORTID_MULTITOUCH;
PtpReport.IsButtonClicked = 0;

UINT timestamp;
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(
DeviceContext->InputQueue,
Expand Down Expand Up @@ -467,23 +465,16 @@ AmtPtpServiceTouchInputInterruptType5(
goto exit;
}

QueryPerformanceCounter(
&CurrentPerfCounter
);
full_report = (const struct TRACKPAD_COMBINED_REPORT_TYPE5 *) Buffer;
mt_report = &full_report->MTReport;

// 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;
timestamp = (mt_report->TimestampHigh << 5) | mt_report->TimestampLow;
PtpReport.ScanTime = (USHORT) timestamp * 10;
PtpReport.IsButtonClicked = (UCHAR) mt_report->Button;

// Type 5 finger report
if (DeviceContext->IsSurfaceReportOn) {
raw_n = (NumBytesTransferred - headerSize) / fingerprintSize;
raw_n = (NumBytesTransferred - sizeof(struct TRACKPAD_REPORT_TYPE5)) / sizeof(struct TRACKPAD_FINGER_TYPE5);
if (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;
PtpReport.ContactCount = (UCHAR)raw_n;

Expand All @@ -498,56 +489,55 @@ AmtPtpServiceTouchInputInterruptType5(

// Fingers to array
for (i = 0; i < raw_n; i++) {
f = &mt_report->Fingers[i];

UCHAR *f_base = Buffer + headerSize + DeviceContext->DeviceInfo->tp_delta;
f = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize);
f_type5 = (const struct TRACKPAD_FINGER_TYPE5*) f;

USHORT tmp_x = (*((USHORT*)f_type5)) & 0x1fff;
UINT tmp_y = (INT)(*((UINT*)f_type5));

x = (SHORT) (tmp_x << 3) >> 3;
y = -(INT) (tmp_y << 6) >> 19;
// Sign extend
x = (SHORT) (f->AbsoluteX << 3) >> 3;
y = -(SHORT) (f->AbsoluteY << 3) >> 3;

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;

PtpReport.Contacts[i].ContactID = f_type5->ContactIdentifier.Id;
PtpReport.Contacts[i].ContactID = f->Id;
PtpReport.Contacts[i].X = (USHORT) x;
PtpReport.Contacts[i].Y = (USHORT) y;
PtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f_type5->TouchMajor) << 1) > 0;
// 0x1 = Transition between states
// 0x2 = Floating finger
// 0x4 = Contact/Valid
// I've gotten 0x6 if I press on the trackpad and then keep my finger close
// Note: These values come from my MBP9,2. These also are valid on my MT2
PtpReport.Contacts[i].TipSwitch = (f->State & 0x4) && !(f->State & 0x2);

// 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;
BOOL valid_size = (AmtRawToInteger(f->TouchMinor) << 1) < 345 &&
(AmtRawToInteger(f->TouchMinor) << 1) < 345;

// 1 = thumb, 2 = index, etc etc
// 6 = palm on MT2, 7 = palm on my MBP9,2 (why are these different?)
BOOL valid_finger = f->Finger != 6;
PtpReport.Contacts[i].Confidence = valid_size && valid_finger;

#ifdef INPUT_CONTENT_TRACE
TraceEvents(
TRACE_LEVEL_INFORMATION,
TRACE_INPUT,
"%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, origin = %d",
"%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, finger type = %d, rotate = %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
AmtRawToInteger(f->TouchMajor) << 1,
AmtRawToInteger(f->TouchMinor) << 1,
f->Finger,
f->Orientation
);
#endif
}
}

// Button
if (DeviceContext->IsButtonReportOn) {
if (Buffer[DeviceContext->DeviceInfo->tp_button]) {
PtpReport.IsButtonClicked = TRUE;
}
}

// Write output
Status = WdfMemoryCopyFromBuffer(
RequestMemory,
Expand Down
58 changes: 44 additions & 14 deletions src/AmtPtpDeviceUsbUm/include/AppleDefinition.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,27 +141,57 @@ __declspec(align(2)) struct TRACKPAD_FINGER {
USHORT multi; /* one finger: varies, more fingers: constant */
};

/* Trackpad finger structure for type5 (magic trackpad), le16-aligned */
__declspec(align(2)) struct TRACKPAD_FINGER_TYPE5
#pragma pack( push, 1 )
#pragma warning( push )
#pragma warning( disable : 4200 )

/* Trackpad finger structure for type5 (magic trackpad) */
struct TRACKPAD_FINGER_TYPE5
{
UCHAR AbsoluteX; /* absolute x coodinate */
UCHAR AbsoluteXY; /* absolute x,y coodinate */
UCHAR AbsoluteY[2]; /* absolute y coodinate */
UINT32 AbsoluteX : 13; /* absolute x coordinate */
UINT32 AbsoluteY : 13; /* absolute y coordinate */
UINT32 Finger : 3; /* finger type */
UINT32 State : 3; /* finger State */
UCHAR TouchMajor; /* touch area, major axis */
UCHAR TouchMinor; /* touch area, minor axis */
UCHAR Size; /* tool area, size */
UCHAR Pressure; /* pressure on forcetouch touchpad */
union
{
struct
{
UCHAR Id : 4;
UCHAR Orientation : 4;
} ContactIdentifier;
UCHAR RawOrientationAndOrigin;
};
UCHAR Id : 4; /* slot id */
UCHAR _ : 1;
UCHAR Orientation : 3; /* contact angle */
};

/* Appended Mouse report on front of MT2 USB reports */
struct MOUSE_REPORT
{
UCHAR ReportId;
UCHAR Button;
UCHAR X;
UCHAR Y;
UCHAR _[4];
};

/* Multitouch report from MT2 */
struct TRACKPAD_REPORT_TYPE5
{
UCHAR ReportId;
UINT8 Button : 1;
UINT8 _ : 2;
UINT8 TimestampLow : 5;
UINT16 TimestampHigh;
struct TRACKPAD_FINGER_TYPE5 Fingers[];
};

/* Full trackpad report for mt2 over USB */
struct TRACKPAD_COMBINED_REPORT_TYPE5
{
struct MOUSE_REPORT Mouse;
struct TRACKPAD_REPORT_TYPE5 MTReport;
};

#pragma warning( pop )
#pragma pack( pop )

/* device-specific parameters */
struct BCM5974_PARAM {
int snratio; /* signal-to-noise ratio */
Expand Down
10 changes: 0 additions & 10 deletions src/AmtPtpHidFilter/Device.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,6 @@ PtpFilterConfigureMultiTouch(
pHidPacket = (PHID_XFER_PACKET) &hidPacketBuffer;

if (deviceContext->VendorID == HID_VID_APPLE_USB) {
deviceContext->InputFingerSize = FSIZE_TYPE5;
deviceContext->InputHeaderSize = HOFFSET_TYPE_USB_5;
deviceContext->InputFingerDelta = FDELTA_TYPE5;
deviceContext->InputButtonDelta = BOFFSET_TYPE5;

deviceContext->X.snratio = 250;
deviceContext->X.min = -3678;
deviceContext->X.max = 3934;
Expand All @@ -341,11 +336,6 @@ PtpFilterConfigureMultiTouch(
pHidPacket->reportBuffer[3] = 0x00;
}
else if (deviceContext->VendorID == HID_VID_APPLE_BT) {
deviceContext->InputFingerSize = FSIZE_TYPE5;
deviceContext->InputHeaderSize = HOFFSET_TYPE_BTH_5;
deviceContext->InputFingerDelta = FDELTA_TYPE5;
deviceContext->InputButtonDelta = BOFFSET_TYPE5;

deviceContext->X.snratio = 250;
deviceContext->X.min = -3678;
deviceContext->X.max = 3934;
Expand Down
Loading