├── .gitignore
├── AmtPtpControlPanel
├── AmtPtpControlPanel.csproj
├── AmtPtpControlPanel.sln
├── App.config
├── Main.Designer.cs
├── Main.cs
├── Main.resx
├── Program.cs
├── Properties
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ ├── Resources.resx
│ ├── Settings.Designer.cs
│ └── Settings.settings
├── Resources
│ └── Icon1.ico
└── app.manifest
├── AmtPtpDeviceUsbUm
├── AmtPtpDevice.wprp
├── Device.c
├── Driver.c
├── Hid.c
├── InputInterrupt.c
├── MagicTrackpad2PtpDevice.sln
├── MagicTrackpad2PtpDevice.vcxproj
├── MagicTrackpad2PtpDevice.vcxproj.filters
├── Queue.c
├── Resource.rc
└── include
│ ├── AppleDefinition.h
│ ├── Device.h
│ ├── DeviceFamily
│ ├── Wellspring3.h
│ ├── Wellspring5.h
│ ├── Wellspring6.h
│ ├── Wellspring7A.h
│ ├── Wellspring8.h
│ └── WellspringMt2.h
│ ├── Driver.h
│ ├── Hid.h
│ ├── HidCommon.h
│ ├── ModernTrace.h
│ ├── Queue.h
│ ├── StaticHidRegistry.h
│ ├── Trace.h
│ └── resource.h
├── README.md
└── assets
└── ControlPanel.png
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | bin/
3 | obj/
4 | build/
5 | intermediate/
6 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/AmtPtpControlPanel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}
8 | WinExe
9 | AmtPtpControlPanel
10 | AmtPtpControlPanel
11 | v4.7.2
12 | 512
13 | true
14 | true
15 |
16 |
17 | AnyCPU
18 | true
19 | full
20 | false
21 | bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | AnyCPU
28 | pdbonly
29 | true
30 | bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 | true
37 | bin\x64\Debug\
38 | DEBUG;TRACE
39 | full
40 | x64
41 | 7.3
42 | prompt
43 | true
44 |
45 |
46 | bin\x64\Release\
47 | TRACE
48 | true
49 | pdbonly
50 | x64
51 | 7.3
52 | prompt
53 | true
54 |
55 |
56 | app.manifest
57 |
58 |
59 | Resources\Icon1.ico
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | Form
77 |
78 |
79 | Main.cs
80 |
81 |
82 |
83 |
84 | Main.cs
85 |
86 |
87 | ResXFileCodeGenerator
88 | Resources.Designer.cs
89 | Designer
90 |
91 |
92 | True
93 | Resources.resx
94 | True
95 |
96 |
97 |
98 | SettingsSingleFileGenerator
99 | Settings.Designer.cs
100 |
101 |
102 | True
103 | Settings.settings
104 | True
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/AmtPtpControlPanel.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.33801.447
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmtPtpControlPanel", "AmtPtpControlPanel.csproj", "{EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x64 = Debug|x64
12 | Release|Any CPU = Release|Any CPU
13 | Release|x64 = Release|x64
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Debug|x64.ActiveCfg = Debug|x64
19 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Debug|x64.Build.0 = Debug|x64
20 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Release|x64.ActiveCfg = Release|x64
23 | {EE1C7A99-9593-4D6A-889B-D75EEA2DE6AB}.Release|x64.Build.0 = Release|x64
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {EF892ED6-EFF6-4552-89C8-4A58160848EC}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Main.Designer.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace AmtPtpControlPanel
3 | {
4 | partial class Main
5 | {
6 | ///
7 | /// Required designer variable.
8 | ///
9 | private System.ComponentModel.IContainer components = null;
10 |
11 | ///
12 | /// Clean up any resources being used.
13 | ///
14 | /// true if managed resources should be disposed; otherwise, false.
15 | protected override void Dispose(bool disposing)
16 | {
17 | if (disposing && (components != null))
18 | {
19 | components.Dispose();
20 | }
21 | base.Dispose(disposing);
22 | }
23 |
24 | #region Windows Form Designer generated code
25 |
26 | ///
27 | /// Required method for Designer support - do not modify
28 | /// the contents of this method with the code editor.
29 | ///
30 | private void InitializeComponent()
31 | {
32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Main));
33 | this.ctlInstallDriver = new System.Windows.Forms.Button();
34 | this.ctlApply = new System.Windows.Forms.Button();
35 | this.ctlFeedback = new System.Windows.Forms.TrackBar();
36 | this.ctlLightLabel = new System.Windows.Forms.Label();
37 | this.ctlMediumLabel = new System.Windows.Forms.Label();
38 | this.ctlFirmLabel = new System.Windows.Forms.Label();
39 | this.ctlSilentClicking = new System.Windows.Forms.CheckBox();
40 | this.ctlMacOSClickOptions = new System.Windows.Forms.RadioButton();
41 | this.groupBox1 = new System.Windows.Forms.GroupBox();
42 | this.groupBox2 = new System.Windows.Forms.GroupBox();
43 | this.ctlMaximumFeedback = new System.Windows.Forms.RadioButton();
44 | this.ctlDisableFeedback = new System.Windows.Forms.RadioButton();
45 | this.ctlFocusHack = new System.Windows.Forms.TextBox();
46 | this.groupBox3 = new System.Windows.Forms.GroupBox();
47 | this.ctlStopSizeLabel = new System.Windows.Forms.Label();
48 | this.ctlStopSizeValue = new System.Windows.Forms.TextBox();
49 | this.ctlStopPressureLabel = new System.Windows.Forms.Label();
50 | this.ctlStopPressureValue = new System.Windows.Forms.TextBox();
51 | this.ctlStopSize = new System.Windows.Forms.RadioButton();
52 | this.ctlStopPressure = new System.Windows.Forms.RadioButton();
53 | this.ctlStopDoNothing = new System.Windows.Forms.RadioButton();
54 | this.groupBox4 = new System.Windows.Forms.GroupBox();
55 | this.ctlIgnoreNearFingers = new System.Windows.Forms.CheckBox();
56 | this.ctlIgnoreButtonFinger = new System.Windows.Forms.CheckBox();
57 | this.ctlPalmRejection = new System.Windows.Forms.CheckBox();
58 | ((System.ComponentModel.ISupportInitialize)(this.ctlFeedback)).BeginInit();
59 | this.groupBox1.SuspendLayout();
60 | this.groupBox2.SuspendLayout();
61 | this.groupBox3.SuspendLayout();
62 | this.groupBox4.SuspendLayout();
63 | this.SuspendLayout();
64 | //
65 | // ctlInstallDriver
66 | //
67 | this.ctlInstallDriver.Location = new System.Drawing.Point(13, 537);
68 | this.ctlInstallDriver.Name = "ctlInstallDriver";
69 | this.ctlInstallDriver.Size = new System.Drawing.Size(195, 33);
70 | this.ctlInstallDriver.TabIndex = 5;
71 | this.ctlInstallDriver.Text = "Install Driver";
72 | this.ctlInstallDriver.UseVisualStyleBackColor = true;
73 | this.ctlInstallDriver.Click += new System.EventHandler(this.ctlInstallDriver_Click);
74 | //
75 | // ctlApply
76 | //
77 | this.ctlApply.Location = new System.Drawing.Point(608, 537);
78 | this.ctlApply.Name = "ctlApply";
79 | this.ctlApply.Size = new System.Drawing.Size(195, 33);
80 | this.ctlApply.TabIndex = 0;
81 | this.ctlApply.Text = "Apply";
82 | this.ctlApply.UseVisualStyleBackColor = true;
83 | this.ctlApply.Click += new System.EventHandler(this.ctlApply_Click);
84 | //
85 | // ctlFeedback
86 | //
87 | this.ctlFeedback.Location = new System.Drawing.Point(53, 106);
88 | this.ctlFeedback.Maximum = 2;
89 | this.ctlFeedback.Name = "ctlFeedback";
90 | this.ctlFeedback.Size = new System.Drawing.Size(227, 56);
91 | this.ctlFeedback.TabIndex = 2;
92 | this.ctlFeedback.Value = 1;
93 | //
94 | // ctlLightLabel
95 | //
96 | this.ctlLightLabel.AutoSize = true;
97 | this.ctlLightLabel.Location = new System.Drawing.Point(50, 145);
98 | this.ctlLightLabel.Name = "ctlLightLabel";
99 | this.ctlLightLabel.Size = new System.Drawing.Size(39, 17);
100 | this.ctlLightLabel.TabIndex = 3;
101 | this.ctlLightLabel.Text = "Light";
102 | //
103 | // ctlMediumLabel
104 | //
105 | this.ctlMediumLabel.AutoSize = true;
106 | this.ctlMediumLabel.Location = new System.Drawing.Point(139, 145);
107 | this.ctlMediumLabel.Name = "ctlMediumLabel";
108 | this.ctlMediumLabel.Size = new System.Drawing.Size(57, 17);
109 | this.ctlMediumLabel.TabIndex = 4;
110 | this.ctlMediumLabel.Text = "Medium";
111 | //
112 | // ctlFirmLabel
113 | //
114 | this.ctlFirmLabel.AutoSize = true;
115 | this.ctlFirmLabel.Location = new System.Drawing.Point(245, 145);
116 | this.ctlFirmLabel.Name = "ctlFirmLabel";
117 | this.ctlFirmLabel.Size = new System.Drawing.Size(35, 17);
118 | this.ctlFirmLabel.TabIndex = 5;
119 | this.ctlFirmLabel.Text = "Firm";
120 | //
121 | // ctlSilentClicking
122 | //
123 | this.ctlSilentClicking.AutoSize = true;
124 | this.ctlSilentClicking.Location = new System.Drawing.Point(112, 68);
125 | this.ctlSilentClicking.Name = "ctlSilentClicking";
126 | this.ctlSilentClicking.Size = new System.Drawing.Size(115, 21);
127 | this.ctlSilentClicking.TabIndex = 1;
128 | this.ctlSilentClicking.Text = "Silent clicking";
129 | this.ctlSilentClicking.UseVisualStyleBackColor = true;
130 | //
131 | // ctlMacOSClickOptions
132 | //
133 | this.ctlMacOSClickOptions.AutoSize = true;
134 | this.ctlMacOSClickOptions.Location = new System.Drawing.Point(17, 21);
135 | this.ctlMacOSClickOptions.Name = "ctlMacOSClickOptions";
136 | this.ctlMacOSClickOptions.Size = new System.Drawing.Size(194, 21);
137 | this.ctlMacOSClickOptions.TabIndex = 0;
138 | this.ctlMacOSClickOptions.TabStop = true;
139 | this.ctlMacOSClickOptions.Text = "Use macOS Click Options:";
140 | this.ctlMacOSClickOptions.UseVisualStyleBackColor = true;
141 | this.ctlMacOSClickOptions.CheckedChanged += new System.EventHandler(this.ctlClickOptions_CheckedChanged);
142 | //
143 | // groupBox1
144 | //
145 | this.groupBox1.Controls.Add(this.ctlLightLabel);
146 | this.groupBox1.Controls.Add(this.ctlMacOSClickOptions);
147 | this.groupBox1.Controls.Add(this.ctlSilentClicking);
148 | this.groupBox1.Controls.Add(this.ctlFirmLabel);
149 | this.groupBox1.Controls.Add(this.ctlMediumLabel);
150 | this.groupBox1.Controls.Add(this.ctlFeedback);
151 | this.groupBox1.Location = new System.Drawing.Point(12, 12);
152 | this.groupBox1.Name = "groupBox1";
153 | this.groupBox1.Size = new System.Drawing.Size(340, 194);
154 | this.groupBox1.TabIndex = 1;
155 | this.groupBox1.TabStop = false;
156 | //
157 | // groupBox2
158 | //
159 | this.groupBox2.Controls.Add(this.ctlMaximumFeedback);
160 | this.groupBox2.Controls.Add(this.ctlDisableFeedback);
161 | this.groupBox2.Location = new System.Drawing.Point(358, 12);
162 | this.groupBox2.Name = "groupBox2";
163 | this.groupBox2.Size = new System.Drawing.Size(445, 194);
164 | this.groupBox2.TabIndex = 2;
165 | this.groupBox2.TabStop = false;
166 | this.groupBox2.Text = "Click Options NOT available in macOS:";
167 | //
168 | // ctlMaximumFeedback
169 | //
170 | this.ctlMaximumFeedback.AutoSize = true;
171 | this.ctlMaximumFeedback.Location = new System.Drawing.Point(28, 98);
172 | this.ctlMaximumFeedback.Name = "ctlMaximumFeedback";
173 | this.ctlMaximumFeedback.Size = new System.Drawing.Size(332, 21);
174 | this.ctlMaximumFeedback.TabIndex = 1;
175 | this.ctlMaximumFeedback.TabStop = true;
176 | this.ctlMaximumFeedback.Text = "Maximum haptic feedback (very clicky and loud!)";
177 | this.ctlMaximumFeedback.UseVisualStyleBackColor = true;
178 | this.ctlMaximumFeedback.CheckedChanged += new System.EventHandler(this.ctlClickOptions_CheckedChanged);
179 | //
180 | // ctlDisableFeedback
181 | //
182 | this.ctlDisableFeedback.AutoSize = true;
183 | this.ctlDisableFeedback.Location = new System.Drawing.Point(28, 61);
184 | this.ctlDisableFeedback.Name = "ctlDisableFeedback";
185 | this.ctlDisableFeedback.Size = new System.Drawing.Size(398, 21);
186 | this.ctlDisableFeedback.TabIndex = 0;
187 | this.ctlDisableFeedback.TabStop = true;
188 | this.ctlDisableFeedback.Text = "Disable haptic feedback and force touch button completely";
189 | this.ctlDisableFeedback.UseVisualStyleBackColor = true;
190 | this.ctlDisableFeedback.CheckedChanged += new System.EventHandler(this.ctlClickOptions_CheckedChanged);
191 | //
192 | // ctlFocusHack
193 | //
194 | this.ctlFocusHack.Location = new System.Drawing.Point(-32, -32);
195 | this.ctlFocusHack.Name = "ctlFocusHack";
196 | this.ctlFocusHack.Size = new System.Drawing.Size(22, 22);
197 | this.ctlFocusHack.TabIndex = 10;
198 | this.ctlFocusHack.TabStop = false;
199 | //
200 | // groupBox3
201 | //
202 | this.groupBox3.Controls.Add(this.ctlStopSizeLabel);
203 | this.groupBox3.Controls.Add(this.ctlStopSizeValue);
204 | this.groupBox3.Controls.Add(this.ctlStopPressureLabel);
205 | this.groupBox3.Controls.Add(this.ctlStopPressureValue);
206 | this.groupBox3.Controls.Add(this.ctlStopSize);
207 | this.groupBox3.Controls.Add(this.ctlStopPressure);
208 | this.groupBox3.Controls.Add(this.ctlStopDoNothing);
209 | this.groupBox3.Location = new System.Drawing.Point(12, 212);
210 | this.groupBox3.Name = "groupBox3";
211 | this.groupBox3.Size = new System.Drawing.Size(791, 147);
212 | this.groupBox3.TabIndex = 3;
213 | this.groupBox3.TabStop = false;
214 | this.groupBox3.Text = "When you lift your finger from the trackpad:";
215 | //
216 | // ctlStopSizeLabel
217 | //
218 | this.ctlStopSizeLabel.AutoSize = true;
219 | this.ctlStopSizeLabel.Location = new System.Drawing.Point(491, 108);
220 | this.ctlStopSizeLabel.Name = "ctlStopSizeLabel";
221 | this.ctlStopSizeLabel.Size = new System.Drawing.Size(164, 17);
222 | this.ctlStopSizeLabel.TabIndex = 6;
223 | this.ctlStopSizeLabel.Text = "units. (7 is a good value)";
224 | this.ctlStopSizeLabel.Click += new System.EventHandler(this.ctlStop_Click);
225 | //
226 | // ctlStopSizeValue
227 | //
228 | this.ctlStopSizeValue.Location = new System.Drawing.Point(434, 106);
229 | this.ctlStopSizeValue.Name = "ctlStopSizeValue";
230 | this.ctlStopSizeValue.Size = new System.Drawing.Size(51, 22);
231 | this.ctlStopSizeValue.TabIndex = 5;
232 | this.ctlStopSizeValue.Text = "7";
233 | this.ctlStopSizeValue.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
234 | //
235 | // ctlStopPressureLabel
236 | //
237 | this.ctlStopPressureLabel.AutoSize = true;
238 | this.ctlStopPressureLabel.Location = new System.Drawing.Point(419, 71);
239 | this.ctlStopPressureLabel.Name = "ctlStopPressureLabel";
240 | this.ctlStopPressureLabel.Size = new System.Drawing.Size(306, 17);
241 | this.ctlStopPressureLabel.TabIndex = 3;
242 | this.ctlStopPressureLabel.Text = "units. (0 means no pressure; 0 is a good value)";
243 | this.ctlStopPressureLabel.Click += new System.EventHandler(this.ctlStop_Click);
244 | //
245 | // ctlStopPressureValue
246 | //
247 | this.ctlStopPressureValue.Location = new System.Drawing.Point(362, 69);
248 | this.ctlStopPressureValue.Name = "ctlStopPressureValue";
249 | this.ctlStopPressureValue.Size = new System.Drawing.Size(51, 22);
250 | this.ctlStopPressureValue.TabIndex = 2;
251 | this.ctlStopPressureValue.Text = "0";
252 | this.ctlStopPressureValue.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
253 | //
254 | // ctlStopSize
255 | //
256 | this.ctlStopSize.AutoSize = true;
257 | this.ctlStopSize.Location = new System.Drawing.Point(17, 106);
258 | this.ctlStopSize.Name = "ctlStopSize";
259 | this.ctlStopSize.Size = new System.Drawing.Size(453, 21);
260 | this.ctlStopSize.TabIndex = 4;
261 | this.ctlStopSize.TabStop = true;
262 | this.ctlStopSize.Text = "Stop the pointer if the size of the touch area is less than or equal to";
263 | this.ctlStopSize.UseVisualStyleBackColor = true;
264 | this.ctlStopSize.CheckedChanged += new System.EventHandler(this.ctlStop_CheckedChanged);
265 | //
266 | // ctlStopPressure
267 | //
268 | this.ctlStopPressure.AutoSize = true;
269 | this.ctlStopPressure.Location = new System.Drawing.Point(17, 69);
270 | this.ctlStopPressure.Name = "ctlStopPressure";
271 | this.ctlStopPressure.Size = new System.Drawing.Size(372, 21);
272 | this.ctlStopPressure.TabIndex = 1;
273 | this.ctlStopPressure.TabStop = true;
274 | this.ctlStopPressure.Text = "Stop the pointer if the pressure is less than or equal to";
275 | this.ctlStopPressure.UseVisualStyleBackColor = true;
276 | this.ctlStopPressure.CheckedChanged += new System.EventHandler(this.ctlStop_CheckedChanged);
277 | //
278 | // ctlStopDoNothing
279 | //
280 | this.ctlStopDoNothing.AutoSize = true;
281 | this.ctlStopDoNothing.Location = new System.Drawing.Point(17, 32);
282 | this.ctlStopDoNothing.Name = "ctlStopDoNothing";
283 | this.ctlStopDoNothing.Size = new System.Drawing.Size(98, 21);
284 | this.ctlStopDoNothing.TabIndex = 0;
285 | this.ctlStopDoNothing.TabStop = true;
286 | this.ctlStopDoNothing.Text = "Do nothing";
287 | this.ctlStopDoNothing.UseVisualStyleBackColor = true;
288 | this.ctlStopDoNothing.CheckedChanged += new System.EventHandler(this.ctlStop_CheckedChanged);
289 | //
290 | // groupBox4
291 | //
292 | this.groupBox4.Controls.Add(this.ctlPalmRejection);
293 | this.groupBox4.Controls.Add(this.ctlIgnoreButtonFinger);
294 | this.groupBox4.Controls.Add(this.ctlIgnoreNearFingers);
295 | this.groupBox4.Location = new System.Drawing.Point(12, 365);
296 | this.groupBox4.Name = "groupBox4";
297 | this.groupBox4.Size = new System.Drawing.Size(791, 147);
298 | this.groupBox4.TabIndex = 4;
299 | this.groupBox4.TabStop = false;
300 | this.groupBox4.Text = "Other options:";
301 | //
302 | // ctlIgnoreNearFingers
303 | //
304 | this.ctlIgnoreNearFingers.AutoSize = true;
305 | this.ctlIgnoreNearFingers.Location = new System.Drawing.Point(17, 32);
306 | this.ctlIgnoreNearFingers.Name = "ctlIgnoreNearFingers";
307 | this.ctlIgnoreNearFingers.Size = new System.Drawing.Size(400, 21);
308 | this.ctlIgnoreNearFingers.TabIndex = 0;
309 | this.ctlIgnoreNearFingers.Text = "Ignore input from fingers not touching the trackpad surface";
310 | this.ctlIgnoreNearFingers.UseVisualStyleBackColor = true;
311 | //
312 | // ctlIgnoreButtonFinger
313 | //
314 | this.ctlIgnoreButtonFinger.Location = new System.Drawing.Point(17, 58);
315 | this.ctlIgnoreButtonFinger.Name = "ctlIgnoreButtonFinger";
316 | this.ctlIgnoreButtonFinger.Size = new System.Drawing.Size(755, 41);
317 | this.ctlIgnoreButtonFinger.TabIndex = 1;
318 | this.ctlIgnoreButtonFinger.Text = "Ignore input from the finger used to click the force touch button (useful for dra" +
319 | "gging, if you use your thumb to click the button and your index finger to move t" +
320 | "he pointer, for example)";
321 | this.ctlIgnoreButtonFinger.UseVisualStyleBackColor = true;
322 | //
323 | // ctlPalmRejection
324 | //
325 | this.ctlPalmRejection.AutoSize = true;
326 | this.ctlPalmRejection.Location = new System.Drawing.Point(17, 106);
327 | this.ctlPalmRejection.Name = "ctlPalmRejection";
328 | this.ctlPalmRejection.Size = new System.Drawing.Size(124, 21);
329 | this.ctlPalmRejection.TabIndex = 2;
330 | this.ctlPalmRejection.Text = "Palm Rejection";
331 | this.ctlPalmRejection.UseVisualStyleBackColor = true;
332 | //
333 | // Main
334 | //
335 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
336 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
337 | this.ClientSize = new System.Drawing.Size(815, 582);
338 | this.Controls.Add(this.groupBox4);
339 | this.Controls.Add(this.groupBox3);
340 | this.Controls.Add(this.ctlFocusHack);
341 | this.Controls.Add(this.groupBox2);
342 | this.Controls.Add(this.groupBox1);
343 | this.Controls.Add(this.ctlApply);
344 | this.Controls.Add(this.ctlInstallDriver);
345 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
346 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
347 | this.MaximizeBox = false;
348 | this.Name = "Main";
349 | this.Text = "Magic Trackpad 2 Control Panel";
350 | this.Load += new System.EventHandler(this.Main_Load);
351 | ((System.ComponentModel.ISupportInitialize)(this.ctlFeedback)).EndInit();
352 | this.groupBox1.ResumeLayout(false);
353 | this.groupBox1.PerformLayout();
354 | this.groupBox2.ResumeLayout(false);
355 | this.groupBox2.PerformLayout();
356 | this.groupBox3.ResumeLayout(false);
357 | this.groupBox3.PerformLayout();
358 | this.groupBox4.ResumeLayout(false);
359 | this.groupBox4.PerformLayout();
360 | this.ResumeLayout(false);
361 | this.PerformLayout();
362 |
363 | }
364 |
365 | #endregion
366 |
367 | private System.Windows.Forms.Button ctlInstallDriver;
368 | private System.Windows.Forms.Button ctlApply;
369 | private System.Windows.Forms.TrackBar ctlFeedback;
370 | private System.Windows.Forms.Label ctlLightLabel;
371 | private System.Windows.Forms.Label ctlMediumLabel;
372 | private System.Windows.Forms.Label ctlFirmLabel;
373 | private System.Windows.Forms.CheckBox ctlSilentClicking;
374 | private System.Windows.Forms.RadioButton ctlMacOSClickOptions;
375 | private System.Windows.Forms.GroupBox groupBox1;
376 | private System.Windows.Forms.GroupBox groupBox2;
377 | private System.Windows.Forms.RadioButton ctlMaximumFeedback;
378 | private System.Windows.Forms.RadioButton ctlDisableFeedback;
379 | private System.Windows.Forms.TextBox ctlFocusHack;
380 | private System.Windows.Forms.GroupBox groupBox3;
381 | private System.Windows.Forms.Label ctlStopSizeLabel;
382 | private System.Windows.Forms.TextBox ctlStopSizeValue;
383 | private System.Windows.Forms.Label ctlStopPressureLabel;
384 | private System.Windows.Forms.TextBox ctlStopPressureValue;
385 | private System.Windows.Forms.RadioButton ctlStopSize;
386 | private System.Windows.Forms.RadioButton ctlStopPressure;
387 | private System.Windows.Forms.RadioButton ctlStopDoNothing;
388 | private System.Windows.Forms.GroupBox groupBox4;
389 | private System.Windows.Forms.CheckBox ctlIgnoreButtonFinger;
390 | private System.Windows.Forms.CheckBox ctlIgnoreNearFingers;
391 | private System.Windows.Forms.CheckBox ctlPalmRejection;
392 | }
393 | }
394 |
395 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using System.Windows.Forms;
6 |
7 | namespace AmtPtpControlPanel
8 | {
9 | static class Program
10 | {
11 | ///
12 | /// The main entry point for the application.
13 | ///
14 | [STAThread]
15 | static void Main()
16 | {
17 | Application.EnableVisualStyles();
18 | Application.SetCompatibleTextRenderingDefault(false);
19 | Application.Run(new Main());
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("AmtPtpControlPanel")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("AmtPtpControlPanel")]
13 | [assembly: AssemblyCopyright("Copyright © 2024")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("ee1c7a99-9593-4d6a-889b-d75eea2de6ab")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace AmtPtpControlPanel.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AmtPtpControlPanel.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
65 | ///
66 | internal static System.Drawing.Icon Icon1 {
67 | get {
68 | object obj = ResourceManager.GetObject("Icon1", resourceCulture);
69 | return ((System.Drawing.Icon)(obj));
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\Icon1.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
123 |
124 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 |
12 | namespace AmtPtpControlPanel.Properties
13 | {
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
17 | {
18 |
19 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
20 |
21 | public static Settings Default
22 | {
23 | get
24 | {
25 | return defaultInstance;
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AmtPtpControlPanel/Resources/Icon1.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maashrafh/MagicTrackpad2ForWindows/971609319bd85e80e667ae8445b9b1053fadef66/AmtPtpControlPanel/Resources/Icon1.ico
--------------------------------------------------------------------------------
/AmtPtpControlPanel/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
54 |
55 |
56 |
57 | true
58 | true
59 |
60 |
61 |
62 |
63 |
64 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/AmtPtpDevice.wprp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
25 |
28 |
29 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/Device.c:
--------------------------------------------------------------------------------
1 | // Device.c: Device handling events for driver.
2 |
3 | #include
4 | #include "device.tmh"
5 |
6 | _IRQL_requires_(PASSIVE_LEVEL)
7 | static const struct BCM5974_CONFIG*
8 | AmtPtpGetDeviceConfig(
9 | _In_ USB_DEVICE_DESCRIPTOR deviceInfo
10 | )
11 | {
12 | USHORT id = deviceInfo.idProduct;
13 | const struct BCM5974_CONFIG *cfg;
14 |
15 | for (cfg = Bcm5974ConfigTable; cfg->ansi; ++cfg) {
16 | if (cfg->ansi == id || cfg->iso == id || cfg->jis == id) {
17 | return cfg;
18 | }
19 | }
20 |
21 | return NULL;
22 | }
23 |
24 | _IRQL_requires_(PASSIVE_LEVEL)
25 | NTSTATUS
26 | AmtPtpCreateDevice(
27 | _In_ WDFDRIVER Driver,
28 | _Inout_ PWDFDEVICE_INIT DeviceInit
29 | )
30 | {
31 | WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
32 | WDF_DEVICE_PNP_CAPABILITIES pnpCaps;
33 | WDF_OBJECT_ATTRIBUTES deviceAttributes;
34 | PDEVICE_CONTEXT deviceContext;
35 | WDFDEVICE device;
36 | NTSTATUS status;
37 |
38 | UNREFERENCED_PARAMETER(Driver);
39 | PAGED_CODE();
40 |
41 | TraceEvents(
42 | TRACE_LEVEL_INFORMATION,
43 | TRACE_DRIVER,
44 | "%!FUNC! Entry"
45 | );
46 |
47 | // Initialize Power Callback
48 | WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
49 |
50 | // Initialize PNP power event callbacks
51 | pnpPowerCallbacks.EvtDevicePrepareHardware = AmtPtpEvtDevicePrepareHardware;
52 | pnpPowerCallbacks.EvtDeviceD0Entry = AmtPtpEvtDeviceD0Entry;
53 | pnpPowerCallbacks.EvtDeviceD0Exit = AmtPtpEvtDeviceD0Exit;
54 | WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
55 |
56 | // Create WDF device object
57 | WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT);
58 |
59 | status = WdfDeviceCreate(
60 | &DeviceInit,
61 | &deviceAttributes,
62 | &device
63 | );
64 |
65 | if (!NT_SUCCESS(status)) {
66 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER,
67 | "%!FUNC! WdfDeviceCreate failed with Status code %!STATUS!", status);
68 | return status;
69 | }
70 |
71 | //
72 | // Get a pointer to the device context structure that we just associated
73 | // with the device object. We define this structure in the device.h
74 | // header file. DeviceGetContext is an inline function generated by
75 | // using the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro in device.h.
76 | // This function will do the type checking and return the device context.
77 | // If you pass a wrong object handle it will return NULL and assert if
78 | // run under framework verifier mode.
79 | //
80 | deviceContext = DeviceGetContext(device);
81 |
82 | //
83 | // Tell the framework to set the SurpriseRemovalOK in the DeviceCaps so
84 | // that you don't get the popup in usermode
85 | // when you surprise remove the device.
86 | //
87 | WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
88 | pnpCaps.SurpriseRemovalOK = WdfTrue;
89 | WdfDeviceSetPnpCapabilities(
90 | device,
91 | &pnpCaps
92 | );
93 |
94 | //
95 | // Create a device interface so that applications can find and talk
96 | // to us.
97 | //
98 | status = WdfDeviceCreateDeviceInterface(
99 | device,
100 | &GUID_DEVINTERFACE_AmtPtpDevice,
101 | NULL // ReferenceString
102 | );
103 |
104 | if (NT_SUCCESS(status)) {
105 | //
106 | // Initialize the I/O Package and any Queues
107 | //
108 | status = AmtPtpDeviceQueueInitialize(device);
109 | }
110 |
111 | TraceEvents(
112 | TRACE_LEVEL_INFORMATION,
113 | TRACE_DRIVER,
114 | "%!FUNC! Exit"
115 | );
116 |
117 | return status;
118 | }
119 |
120 | NTSTATUS
121 | AmtPtpEvtDevicePrepareHardware(
122 | _In_ WDFDEVICE Device,
123 | _In_ WDFCMRESLIST ResourceList,
124 | _In_ WDFCMRESLIST ResourceListTranslated
125 | )
126 | {
127 |
128 | NTSTATUS status;
129 | PDEVICE_CONTEXT pDeviceContext;
130 | ULONG waitWakeEnable;
131 | WDF_USB_DEVICE_INFORMATION deviceInfo;
132 |
133 | waitWakeEnable = FALSE;
134 |
135 | UNREFERENCED_PARAMETER(ResourceList);
136 | UNREFERENCED_PARAMETER(ResourceListTranslated);
137 | PAGED_CODE();
138 |
139 | TraceEvents(
140 | TRACE_LEVEL_INFORMATION,
141 | TRACE_DRIVER,
142 | "%!FUNC! Entry"
143 | );
144 |
145 | status = STATUS_SUCCESS;
146 | pDeviceContext = DeviceGetContext(Device);
147 |
148 | if (pDeviceContext->UsbDevice == NULL) {
149 | status = WdfUsbTargetDeviceCreate(Device,
150 | WDF_NO_OBJECT_ATTRIBUTES,
151 | &pDeviceContext->UsbDevice
152 | );
153 |
154 | if (!NT_SUCCESS(status)) {
155 | TraceEvents(
156 | TRACE_LEVEL_ERROR,
157 | TRACE_DRIVER,
158 | "%!FUNC! WdfUsbTargetDeviceCreate failed with Status code %!STATUS!",
159 | status
160 | );
161 | return status;
162 | }
163 | }
164 |
165 | // Retrieve device information
166 | WdfUsbTargetDeviceGetDeviceDescriptor(
167 | pDeviceContext->UsbDevice,
168 | &pDeviceContext->DeviceDescriptor
169 | );
170 |
171 | if (NT_SUCCESS(status)) {
172 | // Get correct configuration from conf store
173 | pDeviceContext->DeviceInfo = AmtPtpGetDeviceConfig(pDeviceContext->DeviceDescriptor);
174 | if (pDeviceContext->DeviceInfo == NULL) {
175 | status = STATUS_INVALID_DEVICE_STATE;
176 | TraceEvents(
177 | TRACE_LEVEL_ERROR,
178 | TRACE_DEVICE,
179 | "%!FUNC! failed because device is not found in registry."
180 | );
181 | TraceLoggingWrite(
182 | g_hAmtPtpDeviceTraceProvider,
183 | EVENT_DEVICE_IDENTIFICATION,
184 | TraceLoggingString("AmtPtpEvtDevicePrepareHardware", "Routine"),
185 | TraceLoggingUInt16(pDeviceContext->DeviceDescriptor.idProduct, "idProduct"),
186 | TraceLoggingUInt16(pDeviceContext->DeviceDescriptor.idVendor, "idVendor"),
187 | TraceLoggingString(EVENT_DEVICE_ID_SUBTYPE_NOTFOUND, EVENT_DRIVER_FUNC_SUBTYPE)
188 | );
189 | return status;
190 | }
191 | }
192 |
193 | //
194 | // Retrieve USBD version information, port driver capabilites and device
195 | // capabilites such as speed, power, etc.
196 | //
197 | WDF_USB_DEVICE_INFORMATION_INIT(&deviceInfo);
198 | status = WdfUsbTargetDeviceRetrieveInformation(
199 | pDeviceContext->UsbDevice,
200 | &deviceInfo
201 | );
202 |
203 | if (NT_SUCCESS(status)) {
204 | TraceEvents(
205 | TRACE_LEVEL_INFORMATION,
206 | TRACE_DEVICE,
207 | "%!FUNC! IsDeviceHighSpeed: %s",
208 | (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_AT_HIGH_SPEED) ? "TRUE" : "FALSE");
209 |
210 | TraceEvents(
211 | TRACE_LEVEL_INFORMATION,
212 | TRACE_DEVICE,
213 | "%!FUNC! IsDeviceSelfPowered: %s",
214 | (deviceInfo.Traits & WDF_USB_DEVICE_TRAIT_SELF_POWERED) ? "TRUE" : "FALSE");
215 |
216 | waitWakeEnable = deviceInfo.Traits &
217 | WDF_USB_DEVICE_TRAIT_REMOTE_WAKE_CAPABLE;
218 |
219 | TraceEvents(
220 | TRACE_LEVEL_INFORMATION,
221 | TRACE_DEVICE,
222 | "%!FUNC! IsDeviceRemoteWakeable: %s",
223 | waitWakeEnable ? "TRUE" : "FALSE");
224 |
225 | //
226 | // Save these for use later.
227 | //
228 | pDeviceContext->UsbDeviceTraits = deviceInfo.Traits;
229 | } else {
230 | pDeviceContext->UsbDeviceTraits = 0;
231 | }
232 |
233 | // Select interface to use
234 | status = SelectInterruptInterface(Device);
235 | if (!NT_SUCCESS(status)) {
236 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! SelectInterruptInterface failed with %!STATUS!", status);
237 | return status;
238 | }
239 |
240 | // Set up interrupt
241 | status = AmtPtpConfigContReaderForInterruptEndPoint(pDeviceContext);
242 | if (!NT_SUCCESS(status)) {
243 | TraceEvents(TRACE_LEVEL_ERROR, TRACE_DEVICE, "%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with %!STATUS!", status);
244 | return status;
245 | }
246 |
247 | // Set default settings
248 | pDeviceContext->IsButtonReportOn = TRUE;
249 | pDeviceContext->IsSurfaceReportOn = TRUE;
250 |
251 | TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit");
252 | return status;
253 | }
254 |
255 | _IRQL_requires_(PASSIVE_LEVEL)
256 | NTSTATUS
257 | AmtPtpGetWellspringMode(
258 | _In_ PDEVICE_CONTEXT DeviceContext,
259 | _Out_ BOOL* IsWellspringModeOn
260 | )
261 | {
262 |
263 | NTSTATUS status;
264 | WDF_USB_CONTROL_SETUP_PACKET setupPacket;
265 | WDF_MEMORY_DESCRIPTOR memoryDescriptor;
266 | ULONG cbTransferred;
267 | WDFMEMORY bufHandle = NULL;
268 | unsigned char* buffer;
269 |
270 | status = STATUS_SUCCESS;
271 |
272 | TraceEvents(
273 | TRACE_LEVEL_INFORMATION,
274 | TRACE_DRIVER,
275 | "%!FUNC! Entry"
276 | );
277 |
278 | // Type 3 does not need a mode switch.
279 | if (DeviceContext->DeviceInfo->tp_type == TYPE3) {
280 | *IsWellspringModeOn = TRUE;
281 | return STATUS_SUCCESS;
282 | }
283 |
284 | status = WdfMemoryCreate(
285 | WDF_NO_OBJECT_ATTRIBUTES,
286 | PagedPool,
287 | POOL_TAG_PTP_CONTROL,
288 | DeviceContext->DeviceInfo->um_size,
289 | &bufHandle,
290 | &buffer
291 | );
292 |
293 | if (!NT_SUCCESS(status)) {
294 | goto cleanup;
295 | }
296 |
297 | RtlZeroMemory(
298 | buffer,
299 | DeviceContext->DeviceInfo->um_size
300 | );
301 |
302 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
303 | &memoryDescriptor,
304 | buffer,
305 | sizeof(DeviceContext->DeviceInfo->um_size)
306 | );
307 |
308 | WDF_USB_CONTROL_SETUP_PACKET_INIT(
309 | &setupPacket,
310 | BmRequestDeviceToHost,
311 | BmRequestToInterface,
312 | BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
313 | (USHORT)DeviceContext->DeviceInfo->um_req_val,
314 | (USHORT)DeviceContext->DeviceInfo->um_req_idx
315 | );
316 |
317 | // Set stuffs right
318 | setupPacket.Packet.bm.Request.Type = BmRequestClass;
319 |
320 | status = WdfUsbTargetDeviceSendControlTransferSynchronously(
321 | DeviceContext->UsbDevice,
322 | WDF_NO_HANDLE,
323 | NULL,
324 | &setupPacket,
325 | &memoryDescriptor,
326 | &cbTransferred
327 | );
328 |
329 | // Behavior mismatch: Actual device does not transfer bytes as expected (in length)
330 | // So we do not check um_size as a temporary workaround.
331 | if (!NT_SUCCESS(status)) {
332 | TraceEvents(
333 | TRACE_LEVEL_ERROR,
334 | TRACE_DEVICE,
335 | "%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Read) failed with %!STATUS!, cbTransferred = %llu, um_size = %d",
336 | status,
337 | cbTransferred,
338 | DeviceContext->DeviceInfo->um_size
339 | );
340 | goto cleanup;
341 | }
342 |
343 | // Check mode switch
344 | unsigned char wellspringBit = buffer[DeviceContext->DeviceInfo->um_switch_idx];
345 | *IsWellspringModeOn = wellspringBit == DeviceContext->DeviceInfo->um_switch_on ? TRUE : FALSE;
346 |
347 | cleanup:
348 | TraceEvents(
349 | TRACE_LEVEL_INFORMATION,
350 | TRACE_DRIVER,
351 | "%!FUNC! Exit"
352 | );
353 |
354 | WdfObjectDelete(bufHandle);
355 | return status;
356 |
357 | }
358 |
359 | _IRQL_requires_(PASSIVE_LEVEL)
360 | ULONG ReadSettingValue(
361 | _In_ PWCHAR SettingName,
362 | _In_ ULONG DefaultValue
363 | )
364 | {
365 | WDFKEY key = NULL;
366 | NTSTATUS status;
367 | ULONG value = DefaultValue;
368 | UNICODE_STRING valueName;
369 |
370 | TraceEvents(
371 | TRACE_LEVEL_INFORMATION,
372 | TRACE_DRIVER,
373 | "%!FUNC! Entry (%ws)",
374 | SettingName
375 | );
376 |
377 | status = WdfDriverOpenParametersRegistryKey(
378 | WdfGetDriver(),
379 | KEY_READ,
380 | WDF_NO_OBJECT_ATTRIBUTES,
381 | &key);
382 |
383 | if (!NT_SUCCESS(status))
384 | {
385 | key = NULL;
386 | TraceEvents(
387 | TRACE_LEVEL_ERROR,
388 | TRACE_DEVICE,
389 | "%!FUNC! WdfDriverOpenParametersRegistryKey failed with %!STATUS!",
390 | status
391 | );
392 | goto cleanup;
393 | }
394 |
395 | RtlInitUnicodeString(&valueName, SettingName);
396 |
397 | status = WdfRegistryQueryULong(key, &valueName, &value);
398 | if (!NT_SUCCESS(status))
399 | {
400 | value = DefaultValue;
401 | TraceEvents(
402 | TRACE_LEVEL_ERROR,
403 | TRACE_DEVICE,
404 | "%!FUNC! WdfRegistryQueryULong failed with %!STATUS!",
405 | status
406 | );
407 | goto cleanup;
408 | }
409 |
410 | TraceEvents(
411 | TRACE_LEVEL_INFORMATION,
412 | TRACE_DRIVER,
413 | "%!FUNC! read value of %ws is %u",
414 | SettingName,
415 | value
416 | );
417 |
418 | cleanup:
419 | if (key != NULL)
420 | {
421 | WdfRegistryClose(key);
422 | }
423 |
424 | TraceEvents(
425 | TRACE_LEVEL_INFORMATION,
426 | TRACE_DRIVER,
427 | "%!FUNC! Exit"
428 | );
429 |
430 | return value;
431 | }
432 |
433 | _IRQL_requires_(PASSIVE_LEVEL)
434 | NTSTATUS
435 | AmtPtpSetWellspringMode(
436 | _In_ PDEVICE_CONTEXT DeviceContext,
437 | _In_ BOOL IsWellspringModeOn
438 | )
439 | {
440 |
441 | NTSTATUS status;
442 | WDF_USB_CONTROL_SETUP_PACKET setupPacket;
443 | WDF_MEMORY_DESCRIPTOR memoryDescriptor;
444 | ULONG cbTransferred;
445 | WDFMEMORY bufHandle = NULL;
446 | unsigned char* buffer;
447 |
448 | if (IsWellspringModeOn)
449 | {
450 | ULONG feedbackClick = ReadSettingValue(L"FeedbackClick", 0x08081E);
451 | ULONG feedbackRelease = ReadSettingValue(L"FeedbackRelease", 0x020218);
452 |
453 | AmtPtpSetHapticFeedback(DeviceContext, feedbackClick, feedbackRelease);
454 | }
455 |
456 | TraceEvents(
457 | TRACE_LEVEL_INFORMATION,
458 | TRACE_DRIVER,
459 | "%!FUNC! Entry"
460 | );
461 |
462 | // Type 3 does not need a mode switch.
463 | // However, turn mode on or off as requested.
464 | if (DeviceContext->DeviceInfo->tp_type == TYPE3) {
465 | DeviceContext->IsWellspringModeOn = IsWellspringModeOn;
466 | return STATUS_SUCCESS;
467 | }
468 |
469 | status = WdfMemoryCreate(
470 | WDF_NO_OBJECT_ATTRIBUTES,
471 | PagedPool,
472 | POOL_TAG_PTP_CONTROL,
473 | DeviceContext->DeviceInfo->um_size,
474 | &bufHandle,
475 | &buffer
476 | );
477 |
478 | if (!NT_SUCCESS(status)) {
479 | goto cleanup;
480 | }
481 |
482 | RtlZeroMemory(
483 | buffer,
484 | DeviceContext->DeviceInfo->um_size
485 | );
486 |
487 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
488 | &memoryDescriptor,
489 | buffer,
490 | sizeof(DeviceContext->DeviceInfo->um_size)
491 | );
492 |
493 | WDF_USB_CONTROL_SETUP_PACKET_INIT(
494 | &setupPacket,
495 | BmRequestDeviceToHost,
496 | BmRequestToInterface,
497 | BCM5974_WELLSPRING_MODE_READ_REQUEST_ID,
498 | (USHORT) DeviceContext->DeviceInfo->um_req_val,
499 | (USHORT) DeviceContext->DeviceInfo->um_req_idx
500 | );
501 |
502 | // Set stuffs right
503 | setupPacket.Packet.bm.Request.Type = BmRequestClass;
504 |
505 | status = WdfUsbTargetDeviceSendControlTransferSynchronously(
506 | DeviceContext->UsbDevice,
507 | WDF_NO_HANDLE,
508 | NULL,
509 | &setupPacket,
510 | &memoryDescriptor,
511 | &cbTransferred
512 | );
513 |
514 | // Behavior mismatch: Actual device does not transfer bytes as expected (in length)
515 | // So we do not check um_size as a temporary workaround.
516 | if (!NT_SUCCESS(status)) {
517 | TraceEvents(
518 | TRACE_LEVEL_ERROR,
519 | TRACE_DEVICE,
520 | "%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Read) failed with %!STATUS!, cbTransferred = %llu, um_size = %d",
521 | status,
522 | cbTransferred,
523 | DeviceContext->DeviceInfo->um_size
524 | );
525 | goto cleanup;
526 | }
527 |
528 | // Apply the mode switch
529 | buffer[DeviceContext->DeviceInfo->um_switch_idx] = IsWellspringModeOn ?
530 | (unsigned char) DeviceContext->DeviceInfo->um_switch_on :
531 | (unsigned char) DeviceContext->DeviceInfo->um_switch_off;
532 |
533 | // Write configuration
534 | WDF_USB_CONTROL_SETUP_PACKET_INIT(
535 | &setupPacket,
536 | BmRequestHostToDevice,
537 | BmRequestToInterface,
538 | BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID,
539 | (USHORT) DeviceContext->DeviceInfo->um_req_val,
540 | (USHORT) DeviceContext->DeviceInfo->um_req_idx
541 | );
542 |
543 | // Set stuffs right
544 | setupPacket.Packet.bm.Request.Type = BmRequestClass;
545 |
546 | status = WdfUsbTargetDeviceSendControlTransferSynchronously(
547 | DeviceContext->UsbDevice,
548 | WDF_NO_HANDLE,
549 | NULL,
550 | &setupPacket,
551 | &memoryDescriptor,
552 | &cbTransferred
553 | );
554 |
555 | if (!NT_SUCCESS(status)) {
556 | TraceEvents(
557 | TRACE_LEVEL_ERROR,
558 | TRACE_DEVICE,
559 | "%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Write) failed with %!STATUS!",
560 | status
561 | );
562 | goto cleanup;
563 | }
564 |
565 | // Set status
566 | DeviceContext->IsWellspringModeOn = IsWellspringModeOn;
567 |
568 | cleanup:
569 | TraceEvents(
570 | TRACE_LEVEL_INFORMATION,
571 | TRACE_DRIVER,
572 | "%!FUNC! Exit"
573 | );
574 |
575 | WdfObjectDelete(bufHandle);
576 | return status;
577 |
578 | }
579 |
580 | _IRQL_requires_(PASSIVE_LEVEL)
581 | NTSTATUS
582 | AmtPtpSetHapticFeedback( // --> Based on: https://github.com/dos1/Linux-Magic-Trackpad-2-Driver/blob/master/linux/drivers/hid/hid-magicmouse.c
583 | _In_ PDEVICE_CONTEXT DeviceContext,
584 | _In_ ULONG FeedbackClick,
585 | _In_ ULONG FeedbackRelease
586 | )
587 | {
588 | NTSTATUS status = STATUS_UNSUCCESSFUL;
589 | WDFMEMORY bufHandle = NULL;
590 | PBYTE buffer;
591 | WDF_MEMORY_DESCRIPTOR memoryDescriptor;
592 | WDF_USB_CONTROL_SETUP_PACKET setupPacket;
593 | ULONG cbTransferred;
594 | CONST BYTE mt2Click[] = { 0x22, 0x01, 0x00, 0x78, 0x02, 0x00, 0x24, 0x30, 0x06, 0x01, 0x00, 0x18, 0x48, 0x13 };
595 | CONST BYTE mt2Release[] = { 0x23, 0x01, 0x00, 0x78, 0x02, 0x00, 0x24, 0x30, 0x06, 0x01, 0x00, 0x18, 0x48, 0x13 }; // WARNING: sizeof(mt2Release) MUST BE == TO sizeof(mt2Click)!
596 |
597 | TraceEvents(
598 | TRACE_LEVEL_INFORMATION,
599 | TRACE_DRIVER,
600 | "%!FUNC! Entry"
601 | );
602 |
603 | status = WdfMemoryCreate(
604 | WDF_NO_OBJECT_ATTRIBUTES,
605 | PagedPool,
606 | POOL_TAG_PTP_CONTROL,
607 | sizeof(mt2Click),
608 | &bufHandle,
609 | &buffer
610 | );
611 |
612 | if (!NT_SUCCESS(status)) {
613 | goto cleanup;
614 | }
615 |
616 | RtlCopyMemory(
617 | buffer,
618 | mt2Click,
619 | sizeof(mt2Click)
620 | );
621 |
622 | buffer[2] = (BYTE)(FeedbackClick >> 0);
623 | buffer[5] = (BYTE)(FeedbackClick >> 8);
624 | buffer[10] = (BYTE)(FeedbackClick >> 16);
625 |
626 | WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(
627 | &memoryDescriptor,
628 | buffer,
629 | sizeof(mt2Click)
630 | );
631 |
632 | WDF_USB_CONTROL_SETUP_PACKET_INIT(
633 | &setupPacket,
634 | BmRequestHostToDevice,
635 | BmRequestToInterface,
636 | 9,
637 | 0x0322,
638 | 2
639 | );
640 |
641 | setupPacket.Packet.bm.Request.Type = BmRequestClass;
642 |
643 | status = WdfUsbTargetDeviceSendControlTransferSynchronously(
644 | DeviceContext->UsbDevice,
645 | WDF_NO_HANDLE,
646 | NULL,
647 | &setupPacket,
648 | &memoryDescriptor,
649 | &cbTransferred
650 | );
651 |
652 | if (!NT_SUCCESS(status)) {
653 | TraceEvents(
654 | TRACE_LEVEL_ERROR,
655 | TRACE_DEVICE,
656 | "%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Write) failed with %!STATUS!",
657 | status
658 | );
659 | goto cleanup;
660 | }
661 |
662 | RtlCopyMemory(
663 | buffer,
664 | mt2Release,
665 | sizeof(mt2Release)
666 | );
667 |
668 | buffer[2] = (BYTE)(FeedbackRelease >> 0);
669 | buffer[5] = (BYTE)(FeedbackRelease >> 8);
670 | buffer[10] = (BYTE)(FeedbackRelease >> 16);
671 |
672 | WDF_USB_CONTROL_SETUP_PACKET_INIT(
673 | &setupPacket,
674 | BmRequestHostToDevice,
675 | BmRequestToInterface,
676 | 9,
677 | 0x0323,
678 | 2
679 | );
680 |
681 | setupPacket.Packet.bm.Request.Type = BmRequestClass;
682 |
683 | status = WdfUsbTargetDeviceSendControlTransferSynchronously(
684 | DeviceContext->UsbDevice,
685 | WDF_NO_HANDLE,
686 | NULL,
687 | &setupPacket,
688 | &memoryDescriptor,
689 | &cbTransferred
690 | );
691 |
692 | if (!NT_SUCCESS(status)) {
693 | TraceEvents(
694 | TRACE_LEVEL_ERROR,
695 | TRACE_DEVICE,
696 | "%!FUNC! WdfUsbTargetDeviceSendControlTransferSynchronously (Write) failed with %!STATUS!",
697 | status
698 | );
699 | goto cleanup;
700 | }
701 |
702 | cleanup:
703 | TraceEvents(
704 | TRACE_LEVEL_INFORMATION,
705 | TRACE_DRIVER,
706 | "%!FUNC! Exit"
707 | );
708 |
709 | WdfObjectDelete(bufHandle);
710 | return status;
711 | }
712 |
713 | NTSTATUS
714 | AmtPtpEvtDeviceD0Entry(
715 | _In_ WDFDEVICE Device,
716 | _In_ WDF_POWER_DEVICE_STATE PreviousState
717 | )
718 | {
719 | PDEVICE_CONTEXT pDeviceContext;
720 | NTSTATUS status;
721 | BOOLEAN isTargetStarted;
722 |
723 | pDeviceContext = DeviceGetContext(Device);
724 | isTargetStarted = FALSE;
725 |
726 | TraceEvents(
727 | TRACE_LEVEL_INFORMATION,
728 | TRACE_DRIVER,
729 | "%!FUNC! -->AmtPtpDeviceEvtDeviceD0Entry - coming from %s",
730 | DbgDevicePowerString(PreviousState)
731 | );
732 |
733 | // Check wellspring mode
734 | if (pDeviceContext->IsButtonReportOn || pDeviceContext->IsWellspringModeOn) {
735 | TraceEvents(
736 | TRACE_LEVEL_INFORMATION,
737 | TRACE_DRIVER,
738 | "%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode"
739 | );
740 |
741 | status = AmtPtpSetWellspringMode(
742 | pDeviceContext,
743 | TRUE
744 | );
745 |
746 | if (!NT_SUCCESS(status)) {
747 | TraceEvents(
748 | TRACE_LEVEL_WARNING,
749 | TRACE_DRIVER,
750 | "%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Start Wellspring Mode failed with %!STATUS!",
751 | status
752 | );
753 | }
754 | }
755 |
756 | // Get current time counter
757 | QueryPerformanceCounter(
758 | &pDeviceContext->PerfCounter
759 | );
760 |
761 | //
762 | // Since continuous reader is configured for this interrupt-pipe, we must explicitly start
763 | // the I/O target to get the framework to post read requests.
764 | //
765 | status = WdfIoTargetStart(WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe));
766 | if (!NT_SUCCESS(status)) {
767 | TraceEvents(
768 | TRACE_LEVEL_ERROR,
769 | TRACE_DRIVER,
770 | "%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry - Failed to start interrupt pipe %!STATUS!",
771 | status
772 | );
773 | goto End;
774 | }
775 |
776 | isTargetStarted = TRUE;
777 |
778 | End:
779 |
780 | if (!NT_SUCCESS(status)) {
781 | //
782 | // Failure in D0Entry will lead to device being removed. So let us stop the continuous
783 | // reader in preparation for the ensuing remove.
784 | //
785 | if (isTargetStarted) {
786 | WdfIoTargetStop(
787 | WdfUsbTargetPipeGetIoTarget(pDeviceContext->InterruptPipe),
788 | WdfIoTargetCancelSentIo
789 | );
790 | }
791 | }
792 |
793 | TraceEvents(
794 | TRACE_LEVEL_INFORMATION,
795 | TRACE_DRIVER,
796 | "%!FUNC! <--AmtPtpDeviceEvtDeviceD0Entry"
797 | );
798 |
799 | return status;
800 | }
801 |
802 | NTSTATUS
803 | AmtPtpEvtDeviceD0Exit(
804 | _In_ WDFDEVICE Device,
805 | _In_ WDF_POWER_DEVICE_STATE TargetState
806 | )
807 | {
808 | PDEVICE_CONTEXT pDeviceContext;
809 | NTSTATUS status;
810 |
811 | PAGED_CODE();
812 | status = STATUS_SUCCESS;
813 |
814 | TraceEvents(
815 | TRACE_LEVEL_INFORMATION,
816 | TRACE_DRIVER,
817 | "%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - moving to %s",
818 | DbgDevicePowerString(TargetState)
819 | );
820 |
821 | pDeviceContext = DeviceGetContext(Device);
822 |
823 | // Stop IO Pipe.
824 | WdfIoTargetStop(WdfUsbTargetPipeGetIoTarget(
825 | pDeviceContext->InterruptPipe),
826 | WdfIoTargetCancelSentIo
827 | );
828 |
829 | // Cancel Wellspring mode.
830 | TraceEvents(
831 | TRACE_LEVEL_INFORMATION,
832 | TRACE_DRIVER,
833 | "%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode"
834 | );
835 |
836 | status = AmtPtpSetWellspringMode(
837 | pDeviceContext,
838 | FALSE
839 | );
840 |
841 | if (!NT_SUCCESS(status)) {
842 | TraceEvents(
843 | TRACE_LEVEL_WARNING,
844 | TRACE_DRIVER,
845 | "%!FUNC! -->AmtPtpDeviceEvtDeviceD0Exit - Cancel Wellspring Mode failed with %!STATUS!",
846 | status
847 | );
848 | }
849 |
850 | TraceEvents(
851 | TRACE_LEVEL_INFORMATION,
852 | TRACE_DRIVER,
853 | "%!FUNC! <--AmtPtpDeviceEvtDeviceD0Exit"
854 | );
855 |
856 | return status;
857 | }
858 |
859 | _IRQL_requires_(PASSIVE_LEVEL)
860 | NTSTATUS
861 | SelectInterruptInterface(
862 | _In_ WDFDEVICE Device
863 | )
864 | {
865 | WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
866 | NTSTATUS status = STATUS_SUCCESS;
867 | PDEVICE_CONTEXT pDeviceContext;
868 | WDFUSBPIPE pipe;
869 | WDF_USB_PIPE_INFORMATION pipeInfo;
870 | UCHAR index;
871 | UCHAR numberConfiguredPipes;
872 | WDFUSBINTERFACE usbInterface;
873 |
874 | PAGED_CODE();
875 |
876 | pDeviceContext = DeviceGetContext(Device);
877 | WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
878 | usbInterface = WdfUsbTargetDeviceGetInterface(
879 | pDeviceContext->UsbDevice,
880 | 0
881 | );
882 |
883 | if (NULL == usbInterface) {
884 | status = STATUS_UNSUCCESSFUL;
885 | TraceEvents(
886 | TRACE_LEVEL_ERROR,
887 | TRACE_DEVICE,
888 | "%!FUNC! WdfUsbTargetDeviceGetInterface 0 failed %!STATUS!",
889 | status
890 | );
891 | return status;
892 | }
893 |
894 | configParams.Types.SingleInterface.ConfiguredUsbInterface = usbInterface;
895 | configParams.Types.SingleInterface.NumberConfiguredPipes = WdfUsbInterfaceGetNumConfiguredPipes(usbInterface);
896 |
897 | pDeviceContext->UsbInterface = configParams.Types.SingleInterface.ConfiguredUsbInterface;
898 | numberConfiguredPipes = configParams.Types.SingleInterface.NumberConfiguredPipes;
899 |
900 | //
901 | // Get pipe handles
902 | //
903 | for (index = 0; index < numberConfiguredPipes; index++) {
904 |
905 | WDF_USB_PIPE_INFORMATION_INIT(&pipeInfo);
906 |
907 | pipe = WdfUsbInterfaceGetConfiguredPipe(
908 | pDeviceContext->UsbInterface,
909 | index, //PipeIndex,
910 | &pipeInfo
911 | );
912 |
913 | //
914 | // Tell the framework that it's okay to read less than
915 | // MaximumPacketSize
916 | //
917 | WdfUsbTargetPipeSetNoMaximumPacketSizeCheck(pipe);
918 |
919 | if (WdfUsbPipeTypeInterrupt == pipeInfo.PipeType) {
920 | pDeviceContext->InterruptPipe = pipe;
921 | break;
922 | }
923 |
924 | }
925 |
926 | //
927 | // If we didn't find interrupt pipe, fail the start.
928 | //
929 | if (!pDeviceContext->InterruptPipe) {
930 | status = STATUS_INVALID_DEVICE_STATE;
931 | TraceEvents(
932 | TRACE_LEVEL_ERROR,
933 | TRACE_DEVICE,
934 | "%!FUNC! Device is not configured properly %!STATUS!",
935 | status
936 | );
937 |
938 | return status;
939 | }
940 |
941 | return status;
942 | }
943 |
944 | _IRQL_requires_(PASSIVE_LEVEL)
945 | PCHAR
946 | DbgDevicePowerString(
947 | _In_ WDF_POWER_DEVICE_STATE Type
948 | )
949 | {
950 | switch (Type)
951 | {
952 | case WdfPowerDeviceInvalid:
953 | return "WdfPowerDeviceInvalid";
954 | case WdfPowerDeviceD0:
955 | return "WdfPowerDeviceD0";
956 | case WdfPowerDeviceD1:
957 | return "WdfPowerDeviceD1";
958 | case WdfPowerDeviceD2:
959 | return "WdfPowerDeviceD2";
960 | case WdfPowerDeviceD3:
961 | return "WdfPowerDeviceD3";
962 | case WdfPowerDeviceD3Final:
963 | return "WdfPowerDeviceD3Final";
964 | case WdfPowerDevicePrepareForHibernation:
965 | return "WdfPowerDevicePrepareForHibernation";
966 | case WdfPowerDeviceMaximum:
967 | return "WdfPowerDeviceMaximum";
968 | default:
969 | return "UnKnown Device Power State";
970 | }
971 | }
972 |
973 | _IRQL_requires_(PASSIVE_LEVEL)
974 | NTSTATUS
975 | AmtPtpEmergResetDevice(
976 | _In_ PDEVICE_CONTEXT DeviceContext
977 | )
978 | {
979 |
980 | NTSTATUS status;
981 | TraceEvents(
982 | TRACE_LEVEL_INFORMATION,
983 | TRACE_DRIVER,
984 | "%!FUNC! Entry");
985 |
986 | status = AmtPtpSetWellspringMode(
987 | DeviceContext,
988 | FALSE);
989 |
990 | if (!NT_SUCCESS(status)) {
991 | TraceEvents(
992 | TRACE_LEVEL_ERROR,
993 | TRACE_DEVICE,
994 | "%!FUNC! AmtPtpSetWellspringMode failed with %!STATUS!",
995 | status);
996 | }
997 |
998 | status = AmtPtpSetWellspringMode(
999 | DeviceContext,
1000 | TRUE);
1001 |
1002 | if (!NT_SUCCESS(status)) {
1003 | TraceEvents(
1004 | TRACE_LEVEL_ERROR,
1005 | TRACE_DEVICE,
1006 | "%!FUNC! AmtPtpSetWellspringMode failed with %!STATUS!",
1007 | status);
1008 | }
1009 |
1010 | TraceEvents(
1011 | TRACE_LEVEL_INFORMATION,
1012 | TRACE_DRIVER,
1013 | "%!FUNC! Exit");
1014 |
1015 | return status;
1016 |
1017 | }
1018 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/Driver.c:
--------------------------------------------------------------------------------
1 | // Driver.c: This file contains the driver entry points and callbacks.
2 |
3 | #include
4 | #include "driver.tmh"
5 |
6 | // Declares Windows 10 TraceLogger provider here.
7 | TRACELOGGING_DEFINE_PROVIDER(
8 | g_hAmtPtpDeviceTraceProvider,
9 | "AmtPtpDeviceTraceProvider",
10 | (0x871b1e2d, 0xcc5a, 0x4ade, 0xb7, 0x4e, 0x6c, 0xf1, 0x0, 0x4e, 0xf1, 0x49));
11 |
12 | NTSTATUS
13 | DriverEntry(
14 | _In_ PDRIVER_OBJECT DriverObject,
15 | _In_ PUNICODE_STRING RegistryPath
16 | )
17 | {
18 | WDF_DRIVER_CONFIG config;
19 | NTSTATUS status;
20 | WDF_OBJECT_ATTRIBUTES attributes;
21 |
22 | // Initialize tracing
23 | DriverTraceInit(
24 | DriverObject,
25 | RegistryPath
26 | );
27 |
28 | TraceEvents(
29 | TRACE_LEVEL_INFORMATION,
30 | TRACE_DRIVER,
31 | "%!FUNC! Entry"
32 | );
33 |
34 | //
35 | // Register a cleanup callback so that we can call WPP_CLEANUP when
36 | // the framework driver object is deleted during driver unload.
37 | //
38 | WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
39 | attributes.EvtCleanupCallback = AmtPtpDeviceEvtDriverContextCleanup;
40 |
41 | WDF_DRIVER_CONFIG_INIT(&config,
42 | AmtPtpDeviceEvtDeviceAdd
43 | );
44 |
45 | status = WdfDriverCreate(DriverObject,
46 | RegistryPath,
47 | &attributes,
48 | &config,
49 | WDF_NO_HANDLE
50 | );
51 |
52 | if (!NT_SUCCESS(status)) {
53 | TraceEvents(
54 | TRACE_LEVEL_ERROR,
55 | TRACE_DRIVER,
56 | "%!FUNC! WdfDriverCreate failed %!STATUS!",
57 | status
58 | );
59 | TraceLoggingWrite(
60 | g_hAmtPtpDeviceTraceProvider,
61 | EVENT_DRIVER_FUNCTIONAL,
62 | TraceLoggingString("DriverEntry", "Routine"),
63 | TraceLoggingString("WdfDriverCreate", "Context"),
64 | TraceLoggingInt32(status, "Status"),
65 | TraceLoggingString(EVENT_DRIVER_FUNC_SUBTYPE_CRITFAIL, EVENT_DRIVER_FUNC_SUBTYPE)
66 | );
67 | DriverTraceCleanup(DriverObject);
68 | return status;
69 | }
70 |
71 | TraceEvents(
72 | TRACE_LEVEL_INFORMATION,
73 | TRACE_DRIVER,
74 | "%!FUNC! Exit"
75 | );
76 |
77 | return status;
78 | }
79 |
80 | VOID
81 | DriverTraceInit(
82 | _In_ PDRIVER_OBJECT DriverObject,
83 | _In_ PUNICODE_STRING RegistryPath
84 | )
85 | {
86 | // Initialize WPP Tracing
87 | WPP_INIT_TRACING(
88 | DriverObject,
89 | RegistryPath
90 | );
91 |
92 | // Initialize TraceLogger Tracing
93 | TraceLoggingRegister(g_hAmtPtpDeviceTraceProvider);
94 | }
95 |
96 | VOID
97 | DriverTraceCleanup(
98 | _In_ WDFOBJECT DriverObject
99 | )
100 | {
101 | UNREFERENCED_PARAMETER(DriverObject);
102 |
103 | TraceLoggingUnregister(g_hAmtPtpDeviceTraceProvider);
104 | // This actually directly calls WppCleanupUm() in UMDF drivers
105 | WPP_CLEANUP(WdfDriverWdmGetDriverObject((WDFDRIVER) Driver));
106 | }
107 |
108 | NTSTATUS
109 | AmtPtpDeviceEvtDeviceAdd(
110 | _In_ WDFDRIVER Driver,
111 | _Inout_ PWDFDEVICE_INIT DeviceInit
112 | )
113 | {
114 | NTSTATUS status = STATUS_SUCCESS;
115 |
116 | TraceEvents(
117 | TRACE_LEVEL_INFORMATION,
118 | TRACE_DRIVER,
119 | "%!FUNC! Entry"
120 | );
121 |
122 | TraceEvents(
123 | TRACE_LEVEL_INFORMATION,
124 | TRACE_DRIVER,
125 | "%!FUNC! Set FDO driver filter"
126 | );
127 |
128 | WdfFdoInitSetFilter(DeviceInit);
129 |
130 | status = AmtPtpCreateDevice(
131 | Driver,
132 | DeviceInit
133 | );
134 |
135 | TraceEvents(
136 | TRACE_LEVEL_INFORMATION,
137 | TRACE_DRIVER,
138 | "%!FUNC! Exit"
139 | );
140 | return status;
141 | }
142 |
143 | VOID
144 | AmtPtpDeviceEvtDriverContextCleanup(
145 | _In_ WDFOBJECT DriverObject
146 | )
147 | {
148 | TraceEvents(
149 | TRACE_LEVEL_INFORMATION,
150 | TRACE_DRIVER,
151 | "%!FUNC! Entry"
152 | );
153 |
154 | //
155 | // Stop WPP Tracing
156 | //
157 | DriverTraceCleanup(DriverObject);
158 | }
159 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/InputInterrupt.c:
--------------------------------------------------------------------------------
1 | // InputInterrupt.c: Handles device input event
2 |
3 | #include
4 | #include "InputInterrupt.tmh"
5 |
6 | _IRQL_requires_(PASSIVE_LEVEL)
7 | NTSTATUS
8 | AmtPtpConfigContReaderForInterruptEndPoint(
9 | _In_ PDEVICE_CONTEXT DeviceContext
10 | )
11 | {
12 |
13 | WDF_USB_CONTINUOUS_READER_CONFIG contReaderConfig;
14 | NTSTATUS status;
15 | size_t transferLength = 0;
16 |
17 | TraceEvents(
18 | TRACE_LEVEL_INFORMATION,
19 | TRACE_DRIVER,
20 | "%!FUNC! Entry"
21 | );
22 |
23 | switch (DeviceContext->DeviceInfo->tp_type)
24 | {
25 | case TYPE1:
26 | transferLength = HEADER_TYPE1 + FSIZE_TYPE1 * MAX_FINGERS;
27 | break;
28 | case TYPE2:
29 | transferLength = HEADER_TYPE2 + FSIZE_TYPE2 * MAX_FINGERS;
30 | break;
31 | case TYPE3:
32 | transferLength = HEADER_TYPE3 + FSIZE_TYPE3 * MAX_FINGERS;
33 | break;
34 | case TYPE4:
35 | transferLength = HEADER_TYPE4 + FSIZE_TYPE4 * MAX_FINGERS;
36 | break;
37 | case TYPE5:
38 | transferLength = HEADER_TYPE5 + FSIZE_TYPE5 * MAX_FINGERS;
39 | break;
40 | }
41 |
42 | if (transferLength <= 0) {
43 | status = STATUS_UNKNOWN_REVISION;
44 | return status;
45 | }
46 |
47 | WDF_USB_CONTINUOUS_READER_CONFIG_INIT(
48 | &contReaderConfig,
49 | AmtPtpEvtUsbInterruptPipeReadComplete,
50 | DeviceContext, // Context
51 | transferLength // Calculate transferred length by device information
52 | );
53 |
54 | contReaderConfig.EvtUsbTargetPipeReadersFailed = AmtPtpEvtUsbInterruptReadersFailed;
55 |
56 | // Remember to turn it on in D0 entry
57 | status = WdfUsbTargetPipeConfigContinuousReader(
58 | DeviceContext->InterruptPipe,
59 | &contReaderConfig
60 | );
61 |
62 | if (!NT_SUCCESS(status)) {
63 | TraceEvents(
64 | TRACE_LEVEL_ERROR,
65 | TRACE_DRIVER,
66 | "%!FUNC! AmtPtpConfigContReaderForInterruptEndPoint failed with Status code %!STATUS!",
67 | status
68 | );
69 | return status;
70 | }
71 |
72 | TraceEvents(
73 | TRACE_LEVEL_INFORMATION,
74 | TRACE_DRIVER,
75 | "%!FUNC! Exit"
76 | );
77 |
78 | return STATUS_SUCCESS;
79 |
80 | }
81 |
82 | _IRQL_requires_(PASSIVE_LEVEL)
83 | VOID
84 | AmtPtpEvtUsbInterruptPipeReadComplete(
85 | _In_ WDFUSBPIPE Pipe,
86 | _In_ WDFMEMORY Buffer,
87 | _In_ size_t NumBytesTransferred,
88 | _In_ WDFCONTEXT Context
89 | )
90 | {
91 | UNREFERENCED_PARAMETER(Pipe);
92 |
93 | WDFDEVICE device;
94 | PDEVICE_CONTEXT pDeviceContext = Context;
95 | UCHAR* pBuffer = NULL;
96 | NTSTATUS status;
97 |
98 | TraceEvents(
99 | TRACE_LEVEL_INFORMATION,
100 | TRACE_DRIVER,
101 | "%!FUNC! Entry"
102 | );
103 |
104 | device = WdfObjectContextGetObject(pDeviceContext);
105 | size_t headerSize = (unsigned int) pDeviceContext->DeviceInfo->tp_header;
106 | size_t fingerprintSize = (unsigned int) pDeviceContext->DeviceInfo->tp_fsize;
107 |
108 | if (NumBytesTransferred < headerSize || (NumBytesTransferred - headerSize) % fingerprintSize != 0) {
109 |
110 | TraceEvents(
111 | TRACE_LEVEL_INFORMATION,
112 | TRACE_DRIVER,
113 | "%!FUNC! Malformed input received. Length = %llu. Attempt to reset device.",
114 | NumBytesTransferred
115 | );
116 |
117 | status = AmtPtpEmergResetDevice(pDeviceContext);
118 | if (!NT_SUCCESS(status)) {
119 |
120 | TraceEvents(
121 | TRACE_LEVEL_INFORMATION,
122 | TRACE_DRIVER,
123 | "%!FUNC! AmtPtpEmergResetDevice failed with %!STATUS!",
124 | status
125 | );
126 |
127 | }
128 |
129 | return;
130 | }
131 |
132 | if (!pDeviceContext->IsWellspringModeOn) {
133 |
134 | TraceEvents(
135 | TRACE_LEVEL_WARNING,
136 | TRACE_DRIVER,
137 | "%!FUNC! Routine is called without enabling Wellspring mode"
138 | );
139 |
140 | return;
141 | }
142 |
143 | // Dispatch USB Interrupt routine by device family
144 | switch (pDeviceContext->DeviceInfo->tp_type) {
145 | case TYPE1:
146 | {
147 | TraceEvents(
148 | TRACE_LEVEL_WARNING,
149 | TRACE_DRIVER,
150 | "%!FUNC! Mode not yet supported"
151 | );
152 | break;
153 | }
154 | // Universal routine handler
155 | case TYPE2:
156 | case TYPE3:
157 | case TYPE4:
158 | {
159 | pBuffer = WdfMemoryGetBuffer(
160 | Buffer,
161 | NULL
162 | );
163 |
164 | status = AmtPtpServiceTouchInputInterrupt(
165 | pDeviceContext,
166 | pBuffer,
167 | NumBytesTransferred
168 | );
169 |
170 | if (!NT_SUCCESS(status)) {
171 | TraceEvents(
172 | TRACE_LEVEL_WARNING,
173 | TRACE_DRIVER,
174 | "%!FUNC! AmtPtpServiceTouchInputInterrupt failed with %!STATUS!",
175 | status
176 | );
177 | }
178 | break;
179 | }
180 | // Magic Trackpad 2
181 | case TYPE5:
182 | {
183 | pBuffer = WdfMemoryGetBuffer(
184 | Buffer,
185 | NULL
186 | );
187 | status = AmtPtpServiceTouchInputInterruptType5(
188 | pDeviceContext,
189 | pBuffer,
190 | NumBytesTransferred
191 | );
192 |
193 | if (!NT_SUCCESS(status)) {
194 | TraceEvents(
195 | TRACE_LEVEL_WARNING,
196 | TRACE_DRIVER,
197 | "%!FUNC! AmtPtpServiceTouchInputInterrupt5 failed with %!STATUS!",
198 | status
199 | );
200 | }
201 | break;
202 | }
203 | }
204 |
205 | TraceEvents(
206 | TRACE_LEVEL_INFORMATION,
207 | TRACE_DRIVER,
208 | "%!FUNC! Exit"
209 | );
210 |
211 | }
212 |
213 | _IRQL_requires_(PASSIVE_LEVEL)
214 | BOOLEAN
215 | AmtPtpEvtUsbInterruptReadersFailed(
216 | _In_ WDFUSBPIPE Pipe,
217 | _In_ NTSTATUS Status,
218 | _In_ USBD_STATUS UsbdStatus
219 | )
220 | {
221 | UNREFERENCED_PARAMETER(Pipe);
222 | UNREFERENCED_PARAMETER(UsbdStatus);
223 | UNREFERENCED_PARAMETER(Status);
224 |
225 | return TRUE;
226 | }
227 |
228 | _IRQL_requires_(PASSIVE_LEVEL)
229 | NTSTATUS
230 | AmtPtpServiceTouchInputInterrupt(
231 | _In_ PDEVICE_CONTEXT DeviceContext,
232 | _In_ UCHAR* Buffer,
233 | _In_ size_t NumBytesTransferred
234 | )
235 | {
236 | NTSTATUS Status;
237 | WDFREQUEST Request;
238 | WDFMEMORY RequestMemory;
239 | PTP_REPORT PtpReport;
240 | LARGE_INTEGER CurrentPerfCounter;
241 | LONGLONG PerfCounterDelta;
242 |
243 | const struct TRACKPAD_FINGER *f;
244 |
245 | TraceEvents(
246 | TRACE_LEVEL_INFORMATION,
247 | TRACE_DRIVER,
248 | "%!FUNC! Entry"
249 | );
250 |
251 | size_t raw_n, i = 0;
252 | size_t headerSize = (unsigned int) DeviceContext->DeviceInfo->tp_header;
253 | size_t fingerprintSize = (unsigned int) DeviceContext->DeviceInfo->tp_fsize;
254 | USHORT x = 0, y = 0;
255 |
256 | Status = STATUS_SUCCESS;
257 | PtpReport.ReportID = REPORTID_MULTITOUCH;
258 | PtpReport.IsButtonClicked = 0;
259 |
260 | // Retrieve next PTP touchpad request.
261 | Status = WdfIoQueueRetrieveNextRequest(
262 | DeviceContext->InputQueue,
263 | &Request
264 | );
265 |
266 | if (!NT_SUCCESS(Status)) {
267 | TraceEvents(
268 | TRACE_LEVEL_INFORMATION,
269 | TRACE_DRIVER,
270 | "%!FUNC! No pending PTP request. Interrupt disposed"
271 | );
272 | goto exit;
273 | }
274 |
275 | QueryPerformanceCounter(
276 | &CurrentPerfCounter
277 | );
278 |
279 | // Scan time is in 100us
280 | PerfCounterDelta = (CurrentPerfCounter.QuadPart - DeviceContext->PerfCounter.QuadPart) / 100;
281 | // Only two bytes allocated
282 | if (PerfCounterDelta > 0xFF)
283 | {
284 | PerfCounterDelta = 0xFF;
285 | }
286 |
287 | PtpReport.ScanTime = (USHORT) PerfCounterDelta;
288 |
289 | // Allocate output memory.
290 | Status = WdfRequestRetrieveOutputMemory(
291 | Request,
292 | &RequestMemory
293 | );
294 |
295 | if (!NT_SUCCESS(Status)) {
296 | TraceEvents(
297 | TRACE_LEVEL_ERROR,
298 | TRACE_DRIVER,
299 | "%!FUNC! WdfRequestRetrieveOutputMemory failed with %!STATUS!",
300 | Status
301 | );
302 | goto exit;
303 | }
304 |
305 | // Type 2 touchpad surface report
306 | if (DeviceContext->IsSurfaceReportOn) {
307 | // Handles trackpad surface report here.
308 | raw_n = (NumBytesTransferred - headerSize) / fingerprintSize;
309 | if (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;
310 | PtpReport.ContactCount = (UCHAR) raw_n;
311 |
312 | #ifdef INPUT_CONTENT_TRACE
313 | TraceEvents(
314 | TRACE_LEVEL_INFORMATION,
315 | TRACE_DRIVER,
316 | "%!FUNC! with %llu points.",
317 | raw_n
318 | );
319 | #endif
320 |
321 | // Fingers
322 | for (i = 0; i < raw_n; i++) {
323 |
324 | UCHAR *f_base = Buffer + headerSize + DeviceContext->DeviceInfo->tp_delta;
325 | f = (const struct TRACKPAD_FINGER*) (f_base + i * fingerprintSize);
326 |
327 | // Translate X and Y
328 | x = (AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min) > 0 ?
329 | ((USHORT)(AmtRawToInteger(f->abs_x) - DeviceContext->DeviceInfo->x.min)) : 0;
330 | y = (DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y)) > 0 ?
331 | ((USHORT)(DeviceContext->DeviceInfo->y.max - AmtRawToInteger(f->abs_y))) : 0;
332 |
333 | // Defuzz functions remain the same
334 | // TODO: Implement defuzz later
335 | PtpReport.Contacts[i].ContactID = (UCHAR) i;
336 | PtpReport.Contacts[i].X = x;
337 | PtpReport.Contacts[i].Y = y;
338 | PtpReport.Contacts[i].TipSwitch = (AmtRawToInteger(f->touch_major) << 1) >= 200;
339 | PtpReport.Contacts[i].Confidence = (AmtRawToInteger(f->touch_minor) << 1) > 0;
340 |
341 | #ifdef INPUT_CONTENT_TRACE
342 | TraceEvents(
343 | TRACE_LEVEL_INFORMATION,
344 | TRACE_INPUT,
345 | "%!FUNC!: Point %llu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, origin = %d, PTP Origin = %d",
346 | i,
347 | PtpReport.Contacts[i].X,
348 | PtpReport.Contacts[i].Y,
349 | PtpReport.Contacts[i].TipSwitch,
350 | PtpReport.Contacts[i].Confidence,
351 | AmtRawToInteger(f->touch_major) << 1,
352 | AmtRawToInteger(f->touch_minor) << 1,
353 | AmtRawToInteger(f->origin),
354 | (UCHAR) i
355 | );
356 | #endif
357 | }
358 | }
359 |
360 | // Type 2 touchpad contains integrated trackpad buttons
361 | if (DeviceContext->IsButtonReportOn) {
362 | // Handles trackpad button input here.
363 | if (Buffer[DeviceContext->DeviceInfo->tp_button]) {
364 | PtpReport.IsButtonClicked = TRUE;
365 | }
366 | }
367 |
368 | // Compose final report and write it back
369 | Status = WdfMemoryCopyFromBuffer(
370 | RequestMemory,
371 | 0,
372 | (PVOID) &PtpReport,
373 | sizeof(PTP_REPORT)
374 | );
375 |
376 | if (!NT_SUCCESS(Status)) {
377 | TraceEvents(
378 | TRACE_LEVEL_ERROR,
379 | TRACE_DRIVER,
380 | "%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!",
381 | Status
382 | );
383 | goto exit;
384 | }
385 |
386 | // Set result
387 | WdfRequestSetInformation(
388 | Request,
389 | sizeof(PTP_REPORT)
390 | );
391 |
392 | // Set completion flag
393 | WdfRequestComplete(
394 | Request,
395 | Status
396 | );
397 |
398 | exit:
399 | TraceEvents(
400 | TRACE_LEVEL_INFORMATION,
401 | TRACE_DRIVER,
402 | "%!FUNC! Exit"
403 | );
404 | return Status;
405 |
406 | }
407 |
408 | _IRQL_requires_(PASSIVE_LEVEL)
409 | NTSTATUS
410 | AmtPtpServiceTouchInputInterruptType5(
411 | _In_ PDEVICE_CONTEXT DeviceContext,
412 | _In_ UCHAR* Buffer,
413 | _In_ size_t NumBytesTransferred
414 | )
415 | {
416 |
417 | NTSTATUS Status;
418 | WDFREQUEST Request;
419 | WDFMEMORY RequestMemory;
420 | PTP_REPORT PtpReport;
421 |
422 | const struct TRACKPAD_FINGER_TYPE5* f;
423 | const struct TRACKPAD_REPORT_TYPE5* mt_report;
424 | const struct TRACKPAD_COMBINED_REPORT_TYPE5* full_report;
425 |
426 | TraceEvents(
427 | TRACE_LEVEL_INFORMATION,
428 | TRACE_DRIVER,
429 | "%!FUNC! Entry"
430 | );
431 |
432 | Status = STATUS_SUCCESS;
433 | PtpReport.ReportID = REPORTID_MULTITOUCH;
434 | PtpReport.IsButtonClicked = 0;
435 |
436 | UINT timestamp;
437 | INT x, y = 0;
438 | size_t raw_n, i = 0;
439 |
440 | Status = WdfIoQueueRetrieveNextRequest(
441 | DeviceContext->InputQueue,
442 | &Request
443 | );
444 |
445 | if (!NT_SUCCESS(Status)) {
446 | TraceEvents(
447 | TRACE_LEVEL_INFORMATION,
448 | TRACE_DRIVER,
449 | "%!FUNC! No pending PTP request. Interrupt disposed"
450 | );
451 | goto exit;
452 | }
453 |
454 | Status = WdfRequestRetrieveOutputMemory(
455 | Request,
456 | &RequestMemory
457 | );
458 | if (!NT_SUCCESS(Status)) {
459 | TraceEvents(
460 | TRACE_LEVEL_ERROR,
461 | TRACE_DRIVER,
462 | "%!FUNC! WdfRequestRetrieveOutputBuffer failed with %!STATUS!",
463 | Status
464 | );
465 | goto exit;
466 | }
467 |
468 | full_report = (const struct TRACKPAD_COMBINED_REPORT_TYPE5 *) Buffer;
469 | mt_report = &full_report->MTReport;
470 |
471 | timestamp = (mt_report->TimestampHigh << 5) | mt_report->TimestampLow;
472 | PtpReport.ScanTime = (USHORT) timestamp * 10;
473 | PtpReport.IsButtonClicked = (UCHAR) mt_report->Button;
474 |
475 | if (!DeviceContext->PrevPtpReportAuxAndSettingsInited)
476 | {
477 | DeviceContext->PrevPtpReportAuxAndSettingsInited = TRUE;
478 | DeviceContext->PrevPtpReportAux1.Id = (UINT32)-1;
479 | DeviceContext->PrevPtpReportAux2.Id = (UINT32)-1;
480 | DeviceContext->ButtonDisabled = ReadSettingValue(L"ButtonDisabled", 0) ? TRUE : FALSE;
481 | DeviceContext->StopPressure = ReadSettingValue(L"StopPressure", 0);
482 | DeviceContext->StopSize = ReadSettingValue(L"StopSize", 0xffffffff);
483 | DeviceContext->IgnoreButtonFinger = ReadSettingValue(L"IgnoreButtonFinger", 1) ? TRUE : FALSE;
484 | DeviceContext->IgnoreNearFingers = ReadSettingValue(L"IgnoreNearFingers", 1) ? TRUE : FALSE;
485 | DeviceContext->PalmRejection = ReadSettingValue(L"PalmRejection", 0) ? TRUE : FALSE;
486 | }
487 |
488 | if (DeviceContext->ButtonDisabled)
489 | PtpReport.IsButtonClicked = 0;
490 |
491 | // Type 5 finger report
492 | if (DeviceContext->IsSurfaceReportOn) {
493 | raw_n = (NumBytesTransferred - sizeof(struct TRACKPAD_REPORT_TYPE5)) / sizeof(struct TRACKPAD_FINGER_TYPE5);
494 | if (raw_n >= PTP_MAX_CONTACT_POINTS) raw_n = PTP_MAX_CONTACT_POINTS;
495 | PtpReport.ContactCount = (UCHAR)raw_n;
496 |
497 | #ifdef INPUT_CONTENT_TRACE
498 | TraceEvents(
499 | TRACE_LEVEL_INFORMATION,
500 | TRACE_DRIVER,
501 | "%!FUNC! with %llu points.",
502 | raw_n
503 | );
504 | #endif
505 |
506 | // Fingers to array
507 | for (i = 0; i < raw_n; i++) {
508 | f = &mt_report->Fingers[i];
509 |
510 | // Sign extend
511 | x = (SHORT) (f->AbsoluteX << 3) >> 3;
512 | y = -(SHORT) (f->AbsoluteY << 3) >> 3;
513 |
514 | x = (x - DeviceContext->DeviceInfo->x.min) > 0 ? (x - DeviceContext->DeviceInfo->x.min) : 0;
515 | y = (y - DeviceContext->DeviceInfo->y.min) > 0 ? (y - DeviceContext->DeviceInfo->y.min) : 0;
516 |
517 | PtpReport.Contacts[i].ContactID = f->Id;
518 | // 0x1 = Transition between states
519 | // 0x2 = Floating finger
520 | // 0x4 = Contact/Valid
521 | // I've gotten 0x6 if I press on the trackpad and then keep my finger close
522 | // Note: These values come from my MBP9,2. These also are valid on my MT2
523 | PtpReport.Contacts[i].TipSwitch = (f->State & 0x4) && (DeviceContext->IgnoreNearFingers == FALSE ? TRUE : !(f->State & 0x2));
524 |
525 | // The Microsoft spec says reject any input larger than 25mm. This is not ideal
526 | // for Magic Trackpad 2 - so we raised the threshold a bit higher.
527 | // Or maybe I used the wrong unit? IDK
528 | // BOOL valid_size = (AmtRawToInteger(f->TouchMinor) << 1) < 345 &&
529 | // (AmtRawToInteger(f->TouchMinor) << 1) < 345;
530 |
531 | // 1 = thumb, 2 = index, etc etc
532 | // 6 = palm on MT2, 7 = palm on my MBP9,2 (why are these different?)
533 | // BOOL valid_finger = f->Finger != 6;
534 | PtpReport.Contacts[i].Confidence = DeviceContext->PalmRejection == FALSE ? TRUE : f->Finger != 6; // valid_size && valid_finger;
535 |
536 | #define UINT32_SET_MSB(v) ((UINT32)v | ((UINT32)1 << 31))
537 |
538 | PPTP_REPORT_AUX prev_contact = NULL;
539 | if (
540 | DeviceContext->PrevPtpReportAux1.Id != UINT32_SET_MSB(f->Id) &&
541 | DeviceContext->PrevPtpReportAux2.Id != UINT32_SET_MSB(f->Id) &&
542 | (DeviceContext->IgnoreButtonFinger == FALSE ? TRUE : (!DeviceContext->PrevIsButtonClicked || !PtpReport.IsButtonClicked)) &&
543 | (DeviceContext->StopPressure == 0xffffffff ? TRUE : f->Pressure > DeviceContext->StopPressure) &&
544 | (DeviceContext->StopSize == 0xffffffff ? TRUE : f->Size > DeviceContext->StopSize)
545 | )
546 | {
547 | PPTP_REPORT_AUX contact;
548 |
549 | if (DeviceContext->PrevPtpReportAux1.Id == f->Id)
550 | contact = &DeviceContext->PrevPtpReportAux1;
551 | else if (DeviceContext->PrevPtpReportAux2.Id == f->Id)
552 | contact = &DeviceContext->PrevPtpReportAux2;
553 | else if (!DeviceContext->PrevPtpReportAux1.TipSwitch)
554 | contact = &DeviceContext->PrevPtpReportAux1;
555 | else
556 | contact = &DeviceContext->PrevPtpReportAux2;
557 |
558 | contact->X = (USHORT)x;
559 | contact->Y = (USHORT)y;
560 | contact->Id = f->Id;
561 | contact->TipSwitch = PtpReport.Contacts[i].TipSwitch;
562 | }
563 | else // lock the pointer:
564 | {
565 | size_t j;
566 | for (j = 0; j < 2; j++)
567 | {
568 | PPTP_REPORT_AUX contact = !j ? &DeviceContext->PrevPtpReportAux1 : &DeviceContext->PrevPtpReportAux2;
569 |
570 | if (contact->Id == f->Id || contact->Id == UINT32_SET_MSB(f->Id))
571 | {
572 | contact->TipSwitch = PtpReport.Contacts[i].TipSwitch;
573 |
574 | if (contact->TipSwitch)
575 | {
576 | prev_contact = contact;
577 | contact->Id = UINT32_SET_MSB(contact->Id);
578 | }
579 | else
580 | {
581 | contact->Id = (UINT32)-1;
582 | }
583 | }
584 | }
585 | }
586 | PtpReport.Contacts[i].X = prev_contact ? prev_contact->X : (USHORT)x;
587 | PtpReport.Contacts[i].Y = prev_contact ? prev_contact->Y : (USHORT)y;
588 |
589 | #undef UINT32_SET_MSB
590 |
591 | //#ifdef INPUT_CONTENT_TRACE
592 | TraceEvents(
593 | TRACE_LEVEL_INFORMATION,
594 | TRACE_INPUT,
595 | "%!FUNC!: Point %llu, ContactID = %lu, X = %d, Y = %d, TipSwitch = %d, Confidence = %d, tMajor = %d, tMinor = %d, finger type = %d, rotate = %d, pressure = %d, size = %d",
596 | i,
597 | PtpReport.Contacts[i].ContactID,
598 | PtpReport.Contacts[i].X,
599 | PtpReport.Contacts[i].Y,
600 | PtpReport.Contacts[i].TipSwitch,
601 | PtpReport.Contacts[i].Confidence,
602 | AmtRawToInteger(f->TouchMajor) << 1,
603 | AmtRawToInteger(f->TouchMinor) << 1,
604 | f->Finger,
605 | f->Orientation,
606 | f->Pressure,
607 | f->Size
608 | );
609 | //#endif
610 | }
611 | }
612 |
613 | DeviceContext->PrevIsButtonClicked = PtpReport.IsButtonClicked;
614 |
615 | // Write output
616 | Status = WdfMemoryCopyFromBuffer(
617 | RequestMemory,
618 | 0,
619 | (PVOID) &PtpReport,
620 | sizeof(PTP_REPORT)
621 | );
622 |
623 | if (!NT_SUCCESS(Status)) {
624 | TraceEvents(
625 | TRACE_LEVEL_ERROR,
626 | TRACE_DRIVER,
627 | "%!FUNC! WdfMemoryCopyFromBuffer failed with %!STATUS!",
628 | Status
629 | );
630 | goto exit;
631 | }
632 |
633 | // Set result
634 | WdfRequestSetInformation(
635 | Request,
636 | sizeof(PTP_REPORT)
637 | );
638 |
639 | // Set completion flag
640 | WdfRequestComplete(
641 | Request,
642 | Status
643 | );
644 |
645 | exit:
646 | TraceEvents(
647 | TRACE_LEVEL_INFORMATION,
648 | TRACE_DRIVER,
649 | "%!FUNC! Exit"
650 | );
651 | return Status;
652 |
653 | }
654 |
655 | // Helper function for numberic operation
656 | static inline INT AmtRawToInteger(
657 | _In_ USHORT x
658 | )
659 | {
660 | return (signed short) x;
661 | }
662 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.33801.447
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AmtPtpDeviceUsbUm", "MagicTrackpad2PtpDevice.vcxproj", "{87EFA31B-25EB-4944-A30A-300171BFFF57}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|ARM64 = Debug|ARM64
11 | Debug|x64 = Debug|x64
12 | Release|ARM64 = Release|ARM64
13 | Release|x64 = Release|x64
14 | ReleaseSigned|ARM64 = ReleaseSigned|ARM64
15 | ReleaseSigned|x64 = ReleaseSigned|x64
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.ActiveCfg = Debug|ARM64
19 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.Build.0 = Debug|ARM64
20 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|ARM64.Deploy.0 = Debug|ARM64
21 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.ActiveCfg = Debug|x64
22 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.Build.0 = Debug|x64
23 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Debug|x64.Deploy.0 = Debug|x64
24 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.ActiveCfg = Release|ARM64
25 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.Build.0 = Release|ARM64
26 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|ARM64.Deploy.0 = Release|ARM64
27 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.ActiveCfg = Release|x64
28 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.Build.0 = Release|x64
29 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.Release|x64.Deploy.0 = Release|x64
30 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.ActiveCfg = ReleaseSigned|ARM64
31 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.Build.0 = ReleaseSigned|ARM64
32 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|ARM64.Deploy.0 = ReleaseSigned|ARM64
33 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.ActiveCfg = ReleaseSigned|x64
34 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.Build.0 = ReleaseSigned|x64
35 | {87EFA31B-25EB-4944-A30A-300171BFFF57}.ReleaseSigned|x64.Deploy.0 = ReleaseSigned|x64
36 | EndGlobalSection
37 | GlobalSection(SolutionProperties) = preSolution
38 | HideSolutionNode = FALSE
39 | EndGlobalSection
40 | GlobalSection(ExtensibilityGlobals) = postSolution
41 | SolutionGuid = {9DB74DD3-FF04-422C-A220-CD209446BCA8}
42 | EndGlobalSection
43 | EndGlobal
44 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ReleaseSigned
6 | ARM64
7 |
8 |
9 | ReleaseSigned
10 | x64
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 | Debug
22 | ARM64
23 |
24 |
25 | Release
26 | ARM64
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | {87EFA31B-25EB-4944-A30A-300171BFFF57}
56 | {9181db3b-298d-4e39-a572-55bca4e4ac89}
57 | v4.5
58 | 12.0
59 | Debug
60 | Win32
61 | MagicTrackpad2PtpDevice
62 | AmtPtpDeviceUsbUm
63 |
64 |
65 |
66 | $(LatestTargetPlatformVersion)
67 |
68 |
69 | 10.0.19041.0
70 |
71 |
72 |
73 | Windows10
74 | true
75 | WindowsUserModeDriver10.0
76 | DynamicLibrary
77 | 2
78 | Universal
79 |
80 |
81 | Windows10
82 | false
83 | WindowsUserModeDriver10.0
84 | DynamicLibrary
85 | 2
86 | Universal
87 |
88 |
89 | Windows10
90 | false
91 | WindowsUserModeDriver10.0
92 | DynamicLibrary
93 | 2
94 | Universal
95 |
96 |
97 | Windows10
98 | true
99 | WindowsUserModeDriver10.0
100 | DynamicLibrary
101 | 2
102 | Universal
103 |
104 |
105 | Windows10
106 | false
107 | WindowsUserModeDriver10.0
108 | DynamicLibrary
109 | 2
110 | Universal
111 |
112 |
113 | Windows10
114 | false
115 | WindowsUserModeDriver10.0
116 | DynamicLibrary
117 | 2
118 | Universal
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | DbgengRemoteDebugger
130 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
131 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
132 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
133 | http://timestamp.digicert.com
134 |
135 |
136 | DbgengRemoteDebugger
137 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
138 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
139 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
140 | http://timestamp.digicert.com
141 |
142 |
143 | DbgengRemoteDebugger
144 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
145 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
146 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
147 |
148 |
149 | DbgengRemoteDebugger
150 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
151 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
152 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
153 | http://timestamp.digicert.com
154 |
155 |
156 | DbgengRemoteDebugger
157 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
158 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
159 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
160 | http://timestamp.digicert.com
161 |
162 |
163 | DbgengRemoteDebugger
164 | $(SolutionDir)build\$(ProjectName)\$(Platform)\$(ConfigurationName)\
165 | $(DDK_INC_PATH);$(SolutionDir)intermediate\$(Platform)\$(ConfigurationName)\;$(ProjectDir)include;$(IncludePath)
166 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(ConfigurationName)\
167 |
168 |
169 |
170 | http://timestamp.digicert.com
171 | $(ProductionCertPath)
172 | ProductionSign
173 | Off
174 |
175 |
176 |
177 | true
178 | true
179 | include\trace.h
180 |
181 |
182 | sha256
183 |
184 |
185 |
186 |
187 | true
188 | true
189 | include\trace.h
190 |
191 |
192 | sha256
193 |
194 |
195 |
196 |
197 | true
198 | true
199 | include\trace.h
200 |
201 |
202 | sha256
203 |
204 |
205 |
206 |
207 | true
208 | true
209 | include\trace.h
210 |
211 |
212 |
213 |
214 | true
215 | true
216 | include\trace.h
217 |
218 |
219 |
220 |
221 | true
222 | true
223 | include\trace.h
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/MagicTrackpad2PtpDevice.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {8E41214B-6785-4CFE-B992-037D68949A14}
18 | inf;inv;inx;mof;mc;
19 |
20 |
21 | {d3b4239b-c0e3-4d91-a6ee-730df7a15240}
22 |
23 |
24 |
25 |
26 | Header Files
27 |
28 |
29 | Header Files
30 |
31 |
32 | Header Files
33 |
34 |
35 | Header Files
36 |
37 |
38 | Header Files
39 |
40 |
41 | Header Files
42 |
43 |
44 | Header Files
45 |
46 |
47 | Header Files
48 |
49 |
50 | Header Files
51 |
52 |
53 | Header Files
54 |
55 |
56 | Device Specific Metadata Files
57 |
58 |
59 | Device Specific Metadata Files
60 |
61 |
62 | Device Specific Metadata Files
63 |
64 |
65 | Device Specific Metadata Files
66 |
67 |
68 | Device Specific Metadata Files
69 |
70 |
71 | Device Specific Metadata Files
72 |
73 |
74 |
75 |
76 | Source Files
77 |
78 |
79 | Source Files
80 |
81 |
82 | Source Files
83 |
84 |
85 | Source Files
86 |
87 |
88 | Source Files
89 |
90 |
91 |
92 |
93 | Resource Files
94 |
95 |
96 |
97 |
98 | Resource Files
99 |
100 |
101 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/Queue.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maashrafh/MagicTrackpad2ForWindows/971609319bd85e80e667ae8445b9b1053fadef66/AmtPtpDeviceUsbUm/Queue.c
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/Resource.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maashrafh/MagicTrackpad2ForWindows/971609319bd85e80e667ae8445b9b1053fadef66/AmtPtpDeviceUsbUm/Resource.rc
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/AppleDefinition.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define USB_VENDOR_ID_APPLE 0x05ac
4 |
5 | /* MacbookAir, aka wellspring */
6 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
7 | #define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
8 | #define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
9 | /* MacbookProPenryn, aka wellspring2 */
10 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
11 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
12 | #define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
13 | /* Macbook5,1 (unibody), aka wellspring3 */
14 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236
15 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237
16 | #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238
17 | /* MacbookAir3,2 (unibody), aka wellspring5 */
18 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f
19 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240
20 | #define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241
21 | /* MacbookAir3,1 (unibody), aka wellspring4 */
22 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242
23 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243
24 | #define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244
25 | /* Macbook8 (unibody, March 2011) */
26 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
27 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
28 | #define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
29 | /* MacbookAir4,1 (unibody, July 2011) */
30 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
31 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
32 | #define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
33 | /* MacbookAir4,2 (unibody, July 2011) */
34 | #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
35 | #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
36 | #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
37 | /* Macbook8,2 (unibody) */
38 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252
39 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253
40 | #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254
41 | /* MacbookPro10,1 (unibody, June 2012) */
42 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262
43 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263
44 | #define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264
45 | /* MacbookPro10,2 (unibody, October 2012) */
46 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI 0x0259
47 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO 0x025a
48 | #define USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS 0x025b
49 | /* MacbookAir6,2 (unibody, June 2013) */
50 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
51 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
52 | #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
53 | /* MacbookPro12,1 (2015) */
54 | #define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272
55 | #define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273
56 | #define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274
57 | /* Magic Trackpad 2 (2015) */
58 | #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 0x0265
59 | /* Magic Trackpad 2 USB C (2024) */
60 | #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC 0x0324
61 | /* Apple T2 USB trackpad */
62 | #define USB_DEVICE_ID_APPLE_T2 0x027d
63 |
64 | /* button data structure */
65 | struct TRACKPAD_BUTTON_DATA {
66 | UCHAR unknown1; /* constant */
67 | UCHAR button; /* left button */
68 | UCHAR rel_x; /* relative x coordinate */
69 | UCHAR rel_y; /* relative y coordinate */
70 | };
71 |
72 | /* trackpad header types */
73 | enum TRACKPAD_TYPE {
74 | TYPE1, /* plain trackpad */
75 | TYPE2, /* button integrated in trackpad */
76 | TYPE3, /* additional header fields since June 2013 */
77 | TYPE4, /* additional header field for pressure data */
78 | TYPE5 /* format for magic trackpad 2 */
79 | };
80 |
81 | /* Trackpad finger data offsets, le16-aligned */
82 | #define HEADER_TYPE1 (13 * sizeof(USHORT))
83 | #define HEADER_TYPE2 (15 * sizeof(USHORT))
84 | #define HEADER_TYPE3 (19 * sizeof(USHORT))
85 | #define HEADER_TYPE4 (23 * sizeof(USHORT))
86 | #define HEADER_TYPE5 ( 6 * sizeof(USHORT))
87 |
88 | /* Trackpad button data offsets */
89 | #define BUTTON_TYPE1 0
90 | #define BUTTON_TYPE2 15
91 | #define BUTTON_TYPE3 23
92 | #define BUTTON_TYPE4 31
93 | #define BUTTON_TYPE5 1
94 |
95 | /* List of device capability bits */
96 | #define HAS_INTEGRATED_BUTTON 1
97 |
98 | /* Trackpad finger data block size */
99 | #define FSIZE_TYPE1 (14 * sizeof(USHORT))
100 | #define FSIZE_TYPE2 (14 * sizeof(USHORT))
101 | #define FSIZE_TYPE3 (14 * sizeof(USHORT))
102 | #define FSIZE_TYPE4 (15 * sizeof(USHORT))
103 | #define FSIZE_TYPE5 (9)
104 |
105 | /* Offset from header to finger struct */
106 | #define DELTA_TYPE1 (0 * sizeof(USHORT))
107 | #define DELTA_TYPE2 (0 * sizeof(USHORT))
108 | #define DELTA_TYPE3 (0 * sizeof(USHORT))
109 | #define DELTA_TYPE4 (1 * sizeof(USHORT))
110 | #define DELTA_TYPE5 (0 * sizeof(USHORT))
111 |
112 | /* USB control message mode switch data */
113 | #define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8
114 | #define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8
115 | #define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8
116 | #define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0
117 | #define USBMSG_TYPE5 2, 0x302, 1, 1, 0x1, 0x0
118 |
119 | /* Wellspring initialization constants */
120 | #define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1
121 | #define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9
122 |
123 | /* Trackpad finger data size, empirically at least ten fingers */
124 | #define MAX_FINGERS 16
125 | #define MAX_FINGER_ORIENTATION 16384
126 |
127 | #define BCM5974_MOUSE_SIZE 8
128 |
129 | /* trackpad finger structure, le16-aligned */
130 | __declspec(align(2)) struct TRACKPAD_FINGER {
131 | USHORT origin; /* zero when switching track finger */
132 | USHORT abs_x; /* absolute x coodinate */
133 | USHORT abs_y; /* absolute y coodinate */
134 | USHORT rel_x; /* relative x coodinate */
135 | USHORT rel_y; /* relative y coodinate */
136 | USHORT tool_major; /* tool area, major axis */
137 | USHORT tool_minor; /* tool area, minor axis */
138 | USHORT orientation; /* 16384 when point, else 15 bit angle */
139 | USHORT touch_major; /* touch area, major axis */
140 | USHORT touch_minor; /* touch area, minor axis */
141 | USHORT unused[2]; /* zeros */
142 | USHORT pressure; /* pressure on forcetouch touchpad */
143 | USHORT multi; /* one finger: varies, more fingers: constant */
144 | };
145 |
146 | #pragma pack( push, 1 )
147 | #pragma warning( push )
148 | #pragma warning( disable : 4200 )
149 |
150 | /* Trackpad finger structure for type5 (magic trackpad) */
151 | struct TRACKPAD_FINGER_TYPE5
152 | {
153 | UINT32 AbsoluteX : 13; /* absolute x coordinate */
154 | UINT32 AbsoluteY : 13; /* absolute y coordinate */
155 | UINT32 Finger : 3; /* finger type */
156 | UINT32 State : 3; /* finger State */
157 | UCHAR TouchMajor; /* touch area, major axis */
158 | UCHAR TouchMinor; /* touch area, minor axis */
159 | UCHAR Size; /* tool area, size */
160 | UCHAR Pressure; /* pressure on forcetouch touchpad */
161 | UCHAR Id : 4; /* slot id */
162 | UCHAR _ : 1;
163 | UCHAR Orientation : 3; /* contact angle */
164 | };
165 |
166 | /* Appended Mouse report on front of MT2 USB reports */
167 | struct MOUSE_REPORT
168 | {
169 | UCHAR ReportId;
170 | UCHAR Button;
171 | UCHAR X;
172 | UCHAR Y;
173 | UCHAR _[4];
174 | };
175 |
176 | /* Multitouch report from MT2 */
177 | struct TRACKPAD_REPORT_TYPE5
178 | {
179 | UCHAR ReportId;
180 | UINT8 Button : 1;
181 | UINT8 _ : 2;
182 | UINT8 TimestampLow : 5;
183 | UINT16 TimestampHigh;
184 | struct TRACKPAD_FINGER_TYPE5 Fingers[];
185 | };
186 |
187 | /* Full trackpad report for mt2 over USB */
188 | struct TRACKPAD_COMBINED_REPORT_TYPE5
189 | {
190 | struct MOUSE_REPORT Mouse;
191 | struct TRACKPAD_REPORT_TYPE5 MTReport;
192 | };
193 |
194 | #pragma warning( pop )
195 | #pragma pack( pop )
196 |
197 | /* device-specific parameters */
198 | struct BCM5974_PARAM {
199 | int snratio; /* signal-to-noise ratio */
200 | int min; /* device minimum reading */
201 | int max; /* device maximum reading */
202 | };
203 |
204 | /* device-specific configuration */
205 | struct BCM5974_CONFIG {
206 | int ansi, iso, jis; /* the product id of this device */
207 | int caps; /* device capability bitmask */
208 | int bt_ep; /* the endpoint of the button interface */
209 | int bt_datalen; /* data length of the button interface */
210 | int tp_ep; /* the endpoint of the trackpad interface */
211 | enum TRACKPAD_TYPE tp_type; /* type of trackpad interface */
212 | int tp_header; /* bytes in header block */
213 | int tp_datalen; /* data length of the trackpad interface */
214 | int tp_button; /* offset to button data */
215 | int tp_fsize; /* bytes in single finger block */
216 | int tp_delta; /* offset from header to finger struct */
217 | int um_size; /* usb control message length */
218 | int um_req_val; /* usb control message value */
219 | int um_req_idx; /* usb control message index */
220 | int um_switch_idx; /* usb control message mode switch index */
221 | int um_switch_on; /* usb control message mode switch on */
222 | int um_switch_off; /* usb control message mode switch off */
223 | struct BCM5974_PARAM p; /* finger pressure limits */
224 | struct BCM5974_PARAM w; /* finger width limits */
225 | struct BCM5974_PARAM x; /* horizontal limits */
226 | struct BCM5974_PARAM y; /* vertical limits */
227 | struct BCM5974_PARAM o; /* orientation limits */
228 | };
229 |
230 | #define DATAFORMAT(type) \
231 | type, \
232 | HEADER_##type, \
233 | HEADER_##type + (MAX_FINGERS) * (FSIZE_##type), \
234 | BUTTON_##type, \
235 | FSIZE_##type, \
236 | DELTA_##type, \
237 | USBMSG_##type
238 |
239 | /* logical signal quality */
240 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */
241 | #define SN_WIDTH 25 /* width signal-to-noise ratio */
242 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */
243 | #define SN_ORIENT 10 /* orientation signal-to-noise ratio */
244 |
245 | #define PRESSURE_QUALIFICATION_THRESHOLD 2
246 | #define SIZE_QUALIFICATION_THRESHOLD 9
247 | #define SIZE_MU_LOWER_THRESHOLD 5
248 |
249 | #define PRESSURE_MU_QUALIFICATION_THRESHOLD_TOTAL 15
250 | #define SIZE_MU_QUALIFICATION_THRESHOLD_TOTAL 25
251 |
252 | /* device constants */
253 | static const struct BCM5974_CONFIG Bcm5974ConfigTable[] = {
254 | {
255 | USB_DEVICE_ID_APPLE_WELLSPRING_ANSI,
256 | USB_DEVICE_ID_APPLE_WELLSPRING_ISO,
257 | USB_DEVICE_ID_APPLE_WELLSPRING_JIS,
258 | 0,
259 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
260 | 0x81, DATAFORMAT(TYPE1),
261 | { SN_PRESSURE, 0, 256 },
262 | { SN_WIDTH, 0, 2048 },
263 | { SN_COORD, -4824, 5342 },
264 | { SN_COORD, -172, 5820 },
265 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
266 | },
267 | {
268 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
269 | USB_DEVICE_ID_APPLE_WELLSPRING2_ISO,
270 | USB_DEVICE_ID_APPLE_WELLSPRING2_JIS,
271 | 0,
272 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
273 | 0x81, DATAFORMAT(TYPE1),
274 | { SN_PRESSURE, 0, 256 },
275 | { SN_WIDTH, 0, 2048 },
276 | { SN_COORD, -4824, 4824 },
277 | { SN_COORD, -172, 4290 },
278 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
279 | },
280 | {
281 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
282 | USB_DEVICE_ID_APPLE_WELLSPRING3_ISO,
283 | USB_DEVICE_ID_APPLE_WELLSPRING3_JIS,
284 | HAS_INTEGRATED_BUTTON,
285 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
286 | 0x81, DATAFORMAT(TYPE2),
287 | { SN_PRESSURE, 0, 300 },
288 | { SN_WIDTH, 0, 2048 },
289 | { SN_COORD, -4460, 5166 },
290 | { SN_COORD, -75, 6700 },
291 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
292 | },
293 | {
294 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,
295 | USB_DEVICE_ID_APPLE_WELLSPRING4_ISO,
296 | USB_DEVICE_ID_APPLE_WELLSPRING4_JIS,
297 | HAS_INTEGRATED_BUTTON,
298 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
299 | 0x81, DATAFORMAT(TYPE2),
300 | { SN_PRESSURE, 0, 300 },
301 | { SN_WIDTH, 0, 2048 },
302 | { SN_COORD, -4620, 5140 },
303 | { SN_COORD, -150, 6600 },
304 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
305 | },
306 | {
307 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,
308 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO,
309 | USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS,
310 | HAS_INTEGRATED_BUTTON,
311 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
312 | 0x81, DATAFORMAT(TYPE2),
313 | { SN_PRESSURE, 0, 300 },
314 | { SN_WIDTH, 0, 2048 },
315 | { SN_COORD, -4616, 5112 },
316 | { SN_COORD, -142, 5234 },
317 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
318 | },
319 | {
320 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI,
321 | USB_DEVICE_ID_APPLE_WELLSPRING5_ISO,
322 | USB_DEVICE_ID_APPLE_WELLSPRING5_JIS,
323 | HAS_INTEGRATED_BUTTON,
324 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
325 | 0x81, DATAFORMAT(TYPE2),
326 | { SN_PRESSURE, 0, 300 },
327 | { SN_WIDTH, 0, 2048 },
328 | { SN_COORD, -4415, 5050 },
329 | { SN_COORD, -55, 6680 },
330 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
331 | },
332 | {
333 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,
334 | USB_DEVICE_ID_APPLE_WELLSPRING6_ISO,
335 | USB_DEVICE_ID_APPLE_WELLSPRING6_JIS,
336 | HAS_INTEGRATED_BUTTON,
337 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
338 | 0x81, DATAFORMAT(TYPE2),
339 | { SN_PRESSURE, 0, 300 },
340 | { SN_WIDTH, 0, 2048 },
341 | { SN_COORD, -4620, 5140 },
342 | { SN_COORD, -150, 6600 },
343 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
344 | },
345 | {
346 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,
347 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO,
348 | USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS,
349 | HAS_INTEGRATED_BUTTON,
350 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
351 | 0x81, DATAFORMAT(TYPE2),
352 | { SN_PRESSURE, 0, 300 },
353 | { SN_WIDTH, 0, 2048 },
354 | { SN_COORD, -4750, 5280 },
355 | { SN_COORD, -150, 6730 },
356 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
357 | },
358 | {
359 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,
360 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO,
361 | USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS,
362 | HAS_INTEGRATED_BUTTON,
363 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
364 | 0x81, DATAFORMAT(TYPE2),
365 | { SN_PRESSURE, 0, 300 },
366 | { SN_WIDTH, 0, 2048 },
367 | { SN_COORD, -4620, 5140 },
368 | { SN_COORD, -150, 6600 },
369 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
370 | },
371 | {
372 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI,
373 | USB_DEVICE_ID_APPLE_WELLSPRING7_ISO,
374 | USB_DEVICE_ID_APPLE_WELLSPRING7_JIS,
375 | HAS_INTEGRATED_BUTTON,
376 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
377 | 0x81, DATAFORMAT(TYPE2),
378 | { SN_PRESSURE, 0, 300 },
379 | { SN_WIDTH, 0, 2048 },
380 | { SN_COORD, -4750, 5280 },
381 | { SN_COORD, -150, 6730 },
382 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
383 | },
384 | {
385 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ANSI,
386 | USB_DEVICE_ID_APPLE_WELLSPRING7A_ISO,
387 | USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS,
388 | HAS_INTEGRATED_BUTTON,
389 | 0x84, sizeof(struct TRACKPAD_BUTTON_DATA),
390 | 0x81, DATAFORMAT(TYPE2),
391 | { SN_PRESSURE, 0, 300 },
392 | { SN_WIDTH, 0, 2048 },
393 | { SN_COORD, -4750, 5280 },
394 | { SN_COORD, -150, 6730 },
395 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
396 | },
397 | {
398 | USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI,
399 | USB_DEVICE_ID_APPLE_WELLSPRING8_ISO,
400 | USB_DEVICE_ID_APPLE_WELLSPRING8_JIS,
401 | HAS_INTEGRATED_BUTTON,
402 | 0, sizeof(struct TRACKPAD_BUTTON_DATA),
403 | 0x83, DATAFORMAT(TYPE3),
404 | { SN_PRESSURE, 0, 300 },
405 | { SN_WIDTH, 0, 2048 },
406 | { SN_COORD, -4620, 5140 },
407 | { SN_COORD, -150, 6600 },
408 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
409 | },
410 | {
411 | USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI,
412 | USB_DEVICE_ID_APPLE_WELLSPRING9_ISO,
413 | USB_DEVICE_ID_APPLE_WELLSPRING9_JIS,
414 | HAS_INTEGRATED_BUTTON,
415 | 0, sizeof(struct TRACKPAD_BUTTON_DATA),
416 | 0x83, DATAFORMAT(TYPE4),
417 | { SN_PRESSURE, 0, 300 },
418 | { SN_WIDTH, 0, 2048 },
419 | { SN_COORD, -4828, 5345 },
420 | { SN_COORD, -203, 6803 },
421 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
422 | },
423 | {
424 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2,
425 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2,
426 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2,
427 | HAS_INTEGRATED_BUTTON,
428 | 0, sizeof(struct TRACKPAD_BUTTON_DATA),
429 | 0x83, DATAFORMAT(TYPE5),
430 | { SN_PRESSURE, 0, 300 },
431 | { SN_WIDTH, 0, 2048 },
432 | { SN_COORD, -3678, 3934 },
433 | { SN_COORD, -2479, 2586 },
434 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
435 | },
436 | {
437 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC,
438 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC,
439 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC,
440 | HAS_INTEGRATED_BUTTON,
441 | 0, sizeof(struct TRACKPAD_BUTTON_DATA),
442 | 0x83, DATAFORMAT(TYPE5),
443 | { SN_PRESSURE, 0, 300 },
444 | { SN_WIDTH, 0, 2048 },
445 | { SN_COORD, -3678, 3934 },
446 | { SN_COORD, -2479, 2586 },
447 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
448 | },
449 | {
450 | USB_DEVICE_ID_APPLE_T2,
451 | USB_DEVICE_ID_APPLE_T2,
452 | USB_DEVICE_ID_APPLE_T2,
453 | HAS_INTEGRATED_BUTTON,
454 | 0, sizeof(struct TRACKPAD_BUTTON_DATA),
455 | 0x83, DATAFORMAT(TYPE4),
456 | { SN_PRESSURE, 0, 300 },
457 | /* This is incorrect; check actual data later */
458 | { SN_WIDTH, 0, 2048 },
459 | { SN_COORD, -4828, 5345 },
460 | { SN_COORD, -203, 6803 },
461 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
462 | },
463 | };
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/Device.h:
--------------------------------------------------------------------------------
1 | // Device.h: Device definitions
2 |
3 | EXTERN_C_START
4 |
5 | typedef struct _PTP_REPORT_AUX {
6 | USHORT X, Y;
7 | UINT32 Id;
8 | UCHAR TipSwitch;
9 | } PTP_REPORT_AUX, * PPTP_REPORT_AUX;
10 |
11 | // Device context struct
12 | typedef struct _DEVICE_CONTEXT
13 | {
14 | WDFUSBDEVICE UsbDevice;
15 | WDFUSBPIPE InterruptPipe;
16 | WDFUSBINTERFACE UsbInterface;
17 | WDFQUEUE InputQueue;
18 |
19 | USB_DEVICE_DESCRIPTOR DeviceDescriptor;
20 |
21 | const struct BCM5974_CONFIG *DeviceInfo;
22 |
23 | ULONG UsbDeviceTraits;
24 |
25 | UCHAR PressureQualLevel;
26 | UCHAR SgContactSizeQualLevel;
27 | UCHAR MuContactSizeQualLevel;
28 |
29 | BOOL IsWellspringModeOn;
30 | BOOL IsSurfaceReportOn;
31 | BOOL IsButtonReportOn;
32 |
33 | LARGE_INTEGER PerfCounter;
34 |
35 | PTP_REPORT_AUX PrevPtpReportAux1, PrevPtpReportAux2;
36 | BOOL PrevPtpReportAuxAndSettingsInited;
37 | UCHAR PrevIsButtonClicked;
38 | BOOL ButtonDisabled;
39 | ULONG StopPressure;
40 | ULONG StopSize;
41 | BOOL IgnoreButtonFinger;
42 | BOOL IgnoreNearFingers;
43 | BOOL PalmRejection;
44 |
45 | } DEVICE_CONTEXT, *PDEVICE_CONTEXT;
46 |
47 | //
48 | // This macro will generate an inline function called DeviceGetContext
49 | // which will be used to get a pointer to the device context memory
50 | // in a type safe manner.
51 | //
52 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, DeviceGetContext)
53 |
54 | //
55 | // Pool tags
56 | //
57 | #define POOL_TAG_PTP_CONTROL 'PTPC'
58 |
59 | //
60 | // Function to initialize the device's queues and callbacks
61 | //
62 | NTSTATUS
63 | AmtPtpCreateDevice(
64 | _In_ WDFDRIVER Driver,
65 | _Inout_ PWDFDEVICE_INIT DeviceInit
66 | );
67 |
68 | //
69 | // Function to select the device's USB configuration and get a WDFUSBDEVICE
70 | // handle
71 | //
72 | EVT_WDF_DEVICE_PREPARE_HARDWARE AmtPtpEvtDevicePrepareHardware;
73 | EVT_WDF_DEVICE_D0_ENTRY AmtPtpEvtDeviceD0Entry;
74 | EVT_WDF_DEVICE_D0_EXIT AmtPtpEvtDeviceD0Exit;
75 |
76 | _IRQL_requires_(PASSIVE_LEVEL)
77 | NTSTATUS
78 | AmtPtpConfigContReaderForInterruptEndPoint(
79 | _In_ PDEVICE_CONTEXT DeviceContext
80 | );
81 |
82 | _IRQL_requires_(PASSIVE_LEVEL)
83 | NTSTATUS
84 | AmtPtpGetWellspringMode(
85 | _In_ PDEVICE_CONTEXT DeviceContext,
86 | _Out_ BOOL* IsWellspringModeOn
87 | );
88 |
89 | _IRQL_requires_(PASSIVE_LEVEL)
90 | NTSTATUS
91 | SelectInterruptInterface(
92 | _In_ WDFDEVICE Device
93 | );
94 |
95 | _IRQL_requires_(PASSIVE_LEVEL)
96 | NTSTATUS
97 | AmtPtpSetWellspringMode(
98 | _In_ PDEVICE_CONTEXT DeviceContext,
99 | _In_ BOOL IsWellspringModeOn
100 | );
101 |
102 | _IRQL_requires_(PASSIVE_LEVEL)
103 | NTSTATUS
104 | AmtPtpSetHapticFeedback(
105 | _In_ PDEVICE_CONTEXT DeviceContext,
106 | _In_ ULONG FeedbackClick,
107 | _In_ ULONG FeedbackRelease
108 | );
109 |
110 | _IRQL_requires_(PASSIVE_LEVEL)
111 | ULONG ReadSettingValue(
112 | _In_ PWCHAR SettingName,
113 | _In_ ULONG DefaultValue
114 | );
115 |
116 | _IRQL_requires_(PASSIVE_LEVEL)
117 | PCHAR
118 | DbgDevicePowerString(
119 | _In_ WDF_POWER_DEVICE_STATE Type
120 | );
121 |
122 | _IRQL_requires_(PASSIVE_LEVEL)
123 | VOID
124 | AmtPtpEvtUsbInterruptPipeReadComplete(
125 | _In_ WDFUSBPIPE Pipe,
126 | _In_ WDFMEMORY Buffer,
127 | _In_ size_t NumBytesTransferred,
128 | _In_ WDFCONTEXT Context
129 | );
130 |
131 | _IRQL_requires_(PASSIVE_LEVEL)
132 | BOOLEAN
133 | AmtPtpEvtUsbInterruptReadersFailed(
134 | _In_ WDFUSBPIPE Pipe,
135 | _In_ NTSTATUS Status,
136 | _In_ USBD_STATUS UsbdStatus
137 | );
138 |
139 | _IRQL_requires_(PASSIVE_LEVEL)
140 | NTSTATUS
141 | AmtPtpServiceTouchInputInterrupt(
142 | _In_ PDEVICE_CONTEXT DeviceContext,
143 | _In_ UCHAR* Buffer,
144 | _In_ size_t NumBytesTransferred
145 | );
146 |
147 | _IRQL_requires_(PASSIVE_LEVEL)
148 | NTSTATUS
149 | AmtPtpServiceTouchInputInterruptType5(
150 | _In_ PDEVICE_CONTEXT DeviceContext,
151 | _In_ UCHAR* Buffer,
152 | _In_ size_t NumBytesTransferred
153 | );
154 |
155 | _IRQL_requires_(PASSIVE_LEVEL)
156 | NTSTATUS
157 | AmtPtpEmergResetDevice(
158 | _In_ PDEVICE_CONTEXT DeviceContext
159 | );
160 |
161 | ///
162 | /// HID sections
163 | ///
164 |
165 | _IRQL_requires_(PASSIVE_LEVEL)
166 | NTSTATUS
167 | AmtPtpGetHidDescriptor(
168 | _In_ WDFDEVICE Device,
169 | _In_ WDFREQUEST Request
170 | );
171 |
172 | _IRQL_requires_(PASSIVE_LEVEL)
173 | NTSTATUS
174 | AmtPtpGetDeviceAttribs(
175 | _In_ WDFDEVICE Device,
176 | _In_ WDFREQUEST Request
177 | );
178 |
179 | _IRQL_requires_(PASSIVE_LEVEL)
180 | NTSTATUS
181 | AmtPtpGetReportDescriptor(
182 | _In_ WDFDEVICE Device,
183 | _In_ WDFREQUEST Request
184 | );
185 |
186 | _IRQL_requires_(PASSIVE_LEVEL)
187 | NTSTATUS
188 | AmtPtpGetStrings(
189 | _In_ WDFDEVICE Device,
190 | _In_ WDFREQUEST Request
191 | );
192 |
193 | _IRQL_requires_(PASSIVE_LEVEL)
194 | NTSTATUS
195 | AmtPtpReportFeatures(
196 | _In_ WDFDEVICE Device,
197 | _In_ WDFREQUEST Request
198 | );
199 |
200 | _IRQL_requires_(PASSIVE_LEVEL)
201 | NTSTATUS
202 | AmtPtpSetFeatures(
203 | _In_ WDFDEVICE Device,
204 | _In_ WDFREQUEST Request
205 | );
206 |
207 | //
208 | // Utils
209 | //
210 |
211 | _IRQL_requires_(PASSIVE_LEVEL)
212 | NTSTATUS
213 | RequestGetHidXferPacketToReadFromDevice(
214 | _In_ WDFREQUEST Request,
215 | _Out_ HID_XFER_PACKET *Packet
216 | );
217 |
218 | _IRQL_requires_(PASSIVE_LEVEL)
219 | NTSTATUS
220 | RequestGetHidXferPacketToWriteToDevice(
221 | _In_ WDFREQUEST Request,
222 | _Out_ HID_XFER_PACKET *Packet
223 | );
224 |
225 | // Helper function for numberic operation
226 | static inline INT AmtRawToInteger(
227 | _In_ USHORT x
228 | );
229 |
230 | EXTERN_C_END
231 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring3.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | /* This hard-coded size is designed for MacBookAir 7,2 */ \
28 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
29 | LOGICAL_MAXIMUM_2, 0x9a, 0x25, /* Logical Maximum: 9626 (See defintion) */ \
30 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
31 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
32 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
33 | USAGE, 0x30, /* Usage: X */ \
34 | PHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \
35 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
36 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
37 | PHYSICAL_MAXIMUM_2, 0xf8, 0x02, /* Physical Maximum: 760 (See Apple Spec) */ \
38 | LOGICAL_MAXIMUM_2, 0x77, 0x1a, /* Logical Maximum: 6775 (See definition) */ \
39 | USAGE, 0x31, /* Usage: Y */ \
40 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
41 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
42 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
43 | UNIT, 0x00, /* Unit: None */ \
44 | /* End of 4 bytes */ \
45 | END_COLLECTION /* End Collection */ \
46 |
47 | #define AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2 \
48 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
49 | /* Begin a byte */ \
50 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
51 | USAGE, 0x47, /* Usage: Confidence */ \
52 | USAGE, 0x42, /* Usage: Tip switch */ \
53 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
54 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
55 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
56 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
58 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
59 | /* End of a byte */ \
60 | /* Begin of 4 bytes */ \
61 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
62 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
63 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
64 | USAGE, 0x51, /* Usage: Contract Identifier */ \
65 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
66 | /* End of 4 bytes */ \
67 | /* Begin of 4 bytes */ \
68 | /* Size is hard-coded at this moment */ \
69 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
70 | LOGICAL_MAXIMUM_2, 0x9a, 0x25, /* Logical Maximum: 9626 (See defintion) */ \
71 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
72 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
73 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
74 | USAGE, 0x30, /* Usage: X */ \
75 | PHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \
76 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
77 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
78 | PHYSICAL_MAXIMUM_2, 0xf8, 0x02, /* Physical Maximum: 760 (See Apple Spec) */ \
79 | LOGICAL_MAXIMUM_2, 0x77, 0x1a, /* Logical Maximum: 6775 (See definition) */ \
80 | USAGE, 0x31, /* Usage: Y */ \
81 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
82 | /* End of 4 bytes */ \
83 | END_COLLECTION /* End Collection */ \
84 |
85 | #define AAPL_WELLSPRING_3_PTP_TLC \
86 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
87 | USAGE, 0x05, /* Usage: Touch Pad */ \
88 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
89 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
90 | USAGE, 0x22, /* Usage: Finger */ \
91 | AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 1 */ \
92 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
93 | USAGE, 0x22, /* Usage: Finger */ \
94 | AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 2 */ \
95 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
96 | USAGE, 0x22, /* Usage: Finger */ \
97 | AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2, /* 3 */ \
98 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
99 | USAGE, 0x22, /* Usage: Finger */ \
100 | AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_1, /* 4 */ \
101 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
102 | USAGE, 0x22, /* Usage: Finger */ \
103 | AAPL_WELLSPRING_3_PTP_FINGER_COLLECTION_2, /* 5 */ \
104 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
105 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
106 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
107 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
109 | USAGE, 0x56, /* Usage: Scan Time */ \
110 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
111 | USAGE, 0x54, /* Usage: Contact Count */ \
112 | LOGICAL_MAXIMUM, 0x7f, \
113 | REPORT_SIZE, 0x08, \
114 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
115 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
116 | USAGE, 0x01, /* Button 1 */ \
117 | LOGICAL_MAXIMUM, 0x01, \
118 | REPORT_SIZE, 0x01, \
119 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
120 | REPORT_COUNT, 0x07, \
121 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
122 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
123 | REPORT_ID, REPORTID_DEVICE_CAPS, \
124 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
125 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
126 | LOGICAL_MINIMUM, 0x00, \
127 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
128 | REPORT_SIZE, 0x08, \
129 | REPORT_COUNT, 0x02, \
130 | FEATURE, 0x02, \
131 | USAGE_PAGE_1, 0x00, 0xff, \
132 | REPORT_ID, REPORTID_PTPHQA, \
133 | USAGE, 0xc5, \
134 | LOGICAL_MINIMUM, 0x00, \
135 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
136 | REPORT_SIZE, 0x08, \
137 | REPORT_COUNT_2, 0x00, 0x01, \
138 | FEATURE, 0x02, \
139 | END_COLLECTION /* End Collection */
140 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring5.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | /* This hard-coded size is designed for MacBookAir 7,2 */ \
28 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
29 | LOGICAL_MAXIMUM_2, 0xf9, 0x24, /* Logical Maximum: 9465 (See defintion) */ \
30 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
31 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
32 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
33 | USAGE, 0x30, /* Usage: X */ \
34 | PHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \
35 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
36 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
37 | PHYSICAL_MAXIMUM_2, 0x2a, 0x03, /* Physical Maximum: 810 (See Apple Spec) */ \
38 | LOGICAL_MAXIMUM_2, 0x4f, 0x1a, /* Logical Maximum: 6735 (See definition) */ \
39 | USAGE, 0x31, /* Usage: Y */ \
40 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
41 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
42 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
43 | UNIT, 0x00, /* Unit: None */ \
44 | /* End of 4 bytes */ \
45 | END_COLLECTION /* End Collection */ \
46 |
47 | #define AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2 \
48 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
49 | /* Begin a byte */ \
50 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
51 | USAGE, 0x47, /* Usage: Confidence */ \
52 | USAGE, 0x42, /* Usage: Tip switch */ \
53 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
54 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
55 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
56 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
58 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
59 | /* End of a byte */ \
60 | /* Begin of 4 bytes */ \
61 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
62 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
63 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
64 | USAGE, 0x51, /* Usage: Contract Identifier */ \
65 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
66 | /* End of 4 bytes */ \
67 | /* Begin of 4 bytes */ \
68 | /* Size is hard-coded at this moment */ \
69 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
70 | LOGICAL_MAXIMUM_2, 0xf9, 0x24, /* Logical Maximum: 9465 (See defintion) */ \
71 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
72 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
73 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
74 | USAGE, 0x30, /* Usage: X */ \
75 | PHYSICAL_MAXIMUM_2, 0x1a, 0x04, /* Physical Maximum: 1050 (See Apple Spec) */ \
76 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
77 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
78 | PHYSICAL_MAXIMUM_2, 0x2a, 0x03, /* Physical Maximum: 810 (See Apple Spec) */ \
79 | LOGICAL_MAXIMUM_2, 0x4f, 0x1a, /* Logical Maximum: 6735 (See definition) */ \
80 | USAGE, 0x31, /* Usage: Y */ \
81 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
82 | /* End of 4 bytes */ \
83 | END_COLLECTION /* End Collection */ \
84 |
85 | #define AAPL_WELLSPRING_5_PTP_TLC \
86 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
87 | USAGE, 0x05, /* Usage: Touch Pad */ \
88 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
89 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
90 | USAGE, 0x22, /* Usage: Finger */ \
91 | AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 1 */ \
92 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
93 | USAGE, 0x22, /* Usage: Finger */ \
94 | AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 2 */ \
95 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
96 | USAGE, 0x22, /* Usage: Finger */ \
97 | AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2, /* 3 */ \
98 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
99 | USAGE, 0x22, /* Usage: Finger */ \
100 | AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_1, /* 4 */ \
101 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
102 | USAGE, 0x22, /* Usage: Finger */ \
103 | AAPL_WELLSPRING_5_PTP_FINGER_COLLECTION_2, /* 5 */ \
104 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
105 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
106 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
107 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
109 | USAGE, 0x56, /* Usage: Scan Time */ \
110 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
111 | USAGE, 0x54, /* Usage: Contact Count */ \
112 | LOGICAL_MAXIMUM, 0x7f, \
113 | REPORT_SIZE, 0x08, \
114 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
115 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
116 | USAGE, 0x01, /* Button 1 */ \
117 | LOGICAL_MAXIMUM, 0x01, \
118 | REPORT_SIZE, 0x01, \
119 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
120 | REPORT_COUNT, 0x07, \
121 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
122 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
123 | REPORT_ID, REPORTID_DEVICE_CAPS, \
124 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
125 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
126 | LOGICAL_MINIMUM, 0x00, \
127 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
128 | REPORT_SIZE, 0x08, \
129 | REPORT_COUNT, 0x02, \
130 | FEATURE, 0x02, \
131 | USAGE_PAGE_1, 0x00, 0xff, \
132 | REPORT_ID, REPORTID_PTPHQA, \
133 | USAGE, 0xc5, \
134 | LOGICAL_MINIMUM, 0x00, \
135 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
136 | REPORT_SIZE, 0x08, \
137 | REPORT_COUNT_2, 0x00, 0x01, \
138 | FEATURE, 0x02, \
139 | END_COLLECTION /* End Collection */
140 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring6.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | /* This hard-coded size is designed for MacBookAir 7,2 */ \
28 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
29 | LOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \
30 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
31 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
32 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
33 | USAGE, 0x30, /* Usage: X */ \
34 | PHYSICAL_MAXIMUM_2, 0x2b, 0x04, /* Physical Maximum: 1067 (See Apple Spec) */ \
35 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
36 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
37 | PHYSICAL_MAXIMUM_2, 0xfa, 0x02, /* Physical Maximum: 762 (See Apple Spec) */ \
38 | LOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \
39 | USAGE, 0x31, /* Usage: Y */ \
40 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
41 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
42 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
43 | UNIT, 0x00, /* Unit: None */ \
44 | /* End of 4 bytes */ \
45 | END_COLLECTION /* End Collection */ \
46 |
47 | #define AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2 \
48 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
49 | /* Begin a byte */ \
50 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
51 | USAGE, 0x47, /* Usage: Confidence */ \
52 | USAGE, 0x42, /* Usage: Tip switch */ \
53 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
54 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
55 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
56 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
58 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
59 | /* End of a byte */ \
60 | /* Begin of 4 bytes */ \
61 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
62 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
63 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
64 | USAGE, 0x51, /* Usage: Contract Identifier */ \
65 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
66 | /* End of 4 bytes */ \
67 | /* Begin of 4 bytes */ \
68 | /* Size is hard-coded at this moment */ \
69 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
70 | LOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \
71 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
72 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
73 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
74 | USAGE, 0x30, /* Usage: X */ \
75 | PHYSICAL_MAXIMUM_2, 0x2b, 0x04, /* Physical Maximum: 1067 (See Apple Spec) */ \
76 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
77 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
78 | PHYSICAL_MAXIMUM_2, 0xfa, 0x02, /* Physical Maximum: 762 (See Apple Spec) */ \
79 | LOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \
80 | USAGE, 0x31, /* Usage: Y */ \
81 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
82 | /* End of 4 bytes */ \
83 | END_COLLECTION /* End Collection */ \
84 |
85 | #define AAPL_WELLSPRING_6_PTP_TLC \
86 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
87 | USAGE, 0x05, /* Usage: Touch Pad */ \
88 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
89 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
90 | USAGE, 0x22, /* Usage: Finger */ \
91 | AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 1 */ \
92 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
93 | USAGE, 0x22, /* Usage: Finger */ \
94 | AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 2 */ \
95 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
96 | USAGE, 0x22, /* Usage: Finger */ \
97 | AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2, /* 3 */ \
98 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
99 | USAGE, 0x22, /* Usage: Finger */ \
100 | AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_1, /* 4 */ \
101 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
102 | USAGE, 0x22, /* Usage: Finger */ \
103 | AAPL_WELLSPRING_6_PTP_FINGER_COLLECTION_2, /* 5 */ \
104 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
105 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
106 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
107 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
109 | USAGE, 0x56, /* Usage: Scan Time */ \
110 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
111 | USAGE, 0x54, /* Usage: Contact Count */ \
112 | LOGICAL_MAXIMUM, 0x7f, \
113 | REPORT_SIZE, 0x08, \
114 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
115 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
116 | USAGE, 0x01, /* Button 1 */ \
117 | LOGICAL_MAXIMUM, 0x01, \
118 | REPORT_SIZE, 0x01, \
119 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
120 | REPORT_COUNT, 0x07, \
121 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
122 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
123 | REPORT_ID, REPORTID_DEVICE_CAPS, \
124 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
125 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
126 | LOGICAL_MINIMUM, 0x00, \
127 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
128 | REPORT_SIZE, 0x08, \
129 | REPORT_COUNT, 0x02, \
130 | FEATURE, 0x02, \
131 | USAGE_PAGE_1, 0x00, 0xff, \
132 | REPORT_ID, REPORTID_PTPHQA, \
133 | USAGE, 0xc5, \
134 | LOGICAL_MINIMUM, 0x00, \
135 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
136 | REPORT_SIZE, 0x08, \
137 | REPORT_COUNT_2, 0x00, 0x01, \
138 | FEATURE, 0x02, \
139 | END_COLLECTION /* End Collection */
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring7A.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | /* This hard-coded size is designed for MacBookPro 11,1 */ \
28 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
29 | LOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \
30 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
31 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
32 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
33 | USAGE, 0x30, /* Usage: X */ \
34 | PHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \
35 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
36 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
37 | PHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \
38 | LOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \
39 | USAGE, 0x31, /* Usage: Y */ \
40 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
41 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
42 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
43 | UNIT, 0x00, /* Unit: None */ \
44 | /* End of 4 bytes */ \
45 | END_COLLECTION /* End Collection */ \
46 |
47 | #define AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2 \
48 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
49 | /* Begin a byte */ \
50 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
51 | USAGE, 0x47, /* Usage: Confidence */ \
52 | USAGE, 0x42, /* Usage: Tip switch */ \
53 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
54 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
55 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
56 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
58 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
59 | /* End of a byte */ \
60 | /* Begin of 4 bytes */ \
61 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
62 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
63 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
64 | USAGE, 0x51, /* Usage: Contract Identifier */ \
65 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
66 | /* End of 4 bytes */ \
67 | /* Begin of 4 bytes */ \
68 | /* Size is hard-coded at this moment */ \
69 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
70 | LOGICAL_MAXIMUM_2, 0x2e, 0x27, /* Logical Maximum: 10030 (See defintion) */ \
71 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
72 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
73 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
74 | USAGE, 0x30, /* Usage: X */ \
75 | PHYSICAL_MAXIMUM_2, 0x28, 0x04, /* Physical Maximum: 1064 (See Apple Spec) */ \
76 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
77 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
78 | PHYSICAL_MAXIMUM_2, 0x05, 0x03, /* Physical Maximum: 773 (See Apple Spec) */ \
79 | LOGICAL_MAXIMUM_2, 0xe0, 0x1a, /* Logical Maximum: 6880 (See definition) */ \
80 | USAGE, 0x31, /* Usage: Y */ \
81 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
82 | /* End of 4 bytes */ \
83 | END_COLLECTION /* End Collection */ \
84 |
85 | #define AAPL_WELLSPRING_7A_PTP_TLC \
86 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
87 | USAGE, 0x05, /* Usage: Touch Pad */ \
88 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
89 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
90 | USAGE, 0x22, /* Usage: Finger */ \
91 | AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 1 */ \
92 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
93 | USAGE, 0x22, /* Usage: Finger */ \
94 | AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 2 */ \
95 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
96 | USAGE, 0x22, /* Usage: Finger */ \
97 | AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2, /* 3 */ \
98 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
99 | USAGE, 0x22, /* Usage: Finger */ \
100 | AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_1, /* 4 */ \
101 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
102 | USAGE, 0x22, /* Usage: Finger */ \
103 | AAPL_WELLSPRING_7A_PTP_FINGER_COLLECTION_2, /* 5 */ \
104 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
105 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
106 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
107 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
109 | USAGE, 0x56, /* Usage: Scan Time */ \
110 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
111 | USAGE, 0x54, /* Usage: Contact Count */ \
112 | LOGICAL_MAXIMUM, 0x7f, \
113 | REPORT_SIZE, 0x08, \
114 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
115 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
116 | USAGE, 0x01, /* Button 1 */ \
117 | LOGICAL_MAXIMUM, 0x01, \
118 | REPORT_SIZE, 0x01, \
119 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
120 | REPORT_COUNT, 0x07, \
121 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
122 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
123 | REPORT_ID, REPORTID_DEVICE_CAPS, \
124 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
125 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
126 | LOGICAL_MINIMUM, 0x00, \
127 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
128 | REPORT_SIZE, 0x08, \
129 | REPORT_COUNT, 0x02, \
130 | FEATURE, 0x02, \
131 | USAGE_PAGE_1, 0x00, 0xff, \
132 | REPORT_ID, REPORTID_PTPHQA, \
133 | USAGE, 0xc5, \
134 | LOGICAL_MINIMUM, 0x00, \
135 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
136 | REPORT_SIZE, 0x08, \
137 | REPORT_COUNT_2, 0x00, 0x01, \
138 | FEATURE, 0x02, \
139 | END_COLLECTION /* End Collection */
140 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/Wellspring8.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | /* This hard-coded size is designed for MacBookAir 7,2 */ \
28 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
29 | LOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \
30 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
31 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
32 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
33 | USAGE, 0x30, /* Usage: X */ \
34 | PHYSICAL_MAXIMUM_2, 0x15, 0x04, /* Physical Maximum: 1045 (See Apple Spec) */ \
35 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
36 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
37 | PHYSICAL_MAXIMUM_2, 0xee, 0x02, /* Physical Maximum: 750 (See Apple Spec) */ \
38 | LOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \
39 | USAGE, 0x31, /* Usage: Y */ \
40 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
41 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
42 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
43 | UNIT, 0x00, /* Unit: None */ \
44 | /* End of 4 bytes */ \
45 | END_COLLECTION /* End Collection */ \
46 |
47 | #define AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2 \
48 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
49 | /* Begin a byte */ \
50 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
51 | USAGE, 0x47, /* Usage: Confidence */ \
52 | USAGE, 0x42, /* Usage: Tip switch */ \
53 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
54 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
55 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
56 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
58 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
59 | /* End of a byte */ \
60 | /* Begin of 4 bytes */ \
61 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
62 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
63 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
64 | USAGE, 0x51, /* Usage: Contract Identifier */ \
65 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
66 | /* End of 4 bytes */ \
67 | /* Begin of 4 bytes */ \
68 | /* Size is hard-coded at this moment */ \
69 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
70 | LOGICAL_MAXIMUM_2, 0x20, 0x26, /* Logical Maximum: 9760 (See defintion) */ \
71 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
72 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
73 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
74 | USAGE, 0x30, /* Usage: X */ \
75 | PHYSICAL_MAXIMUM_2, 0x15, 0x04, /* Physical Maximum: 1045 (See Apple Spec) */ \
76 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
77 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
78 | PHYSICAL_MAXIMUM_2, 0xee, 0x02, /* Physical Maximum: 750 (See Apple Spec) */ \
79 | LOGICAL_MAXIMUM_2, 0x5e, 0x1a, /* Logical Maximum: 6750 (See definition) */ \
80 | USAGE, 0x31, /* Usage: Y */ \
81 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
82 | /* End of 4 bytes */ \
83 | END_COLLECTION /* End Collection */ \
84 |
85 | #define AAPL_WELLSPRING_8_PTP_TLC \
86 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
87 | USAGE, 0x05, /* Usage: Touch Pad */ \
88 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
89 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
90 | USAGE, 0x22, /* Usage: Finger */ \
91 | AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 1 */ \
92 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
93 | USAGE, 0x22, /* Usage: Finger */ \
94 | AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 2 */ \
95 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
96 | USAGE, 0x22, /* Usage: Finger */ \
97 | AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2, /* 3 */ \
98 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
99 | USAGE, 0x22, /* Usage: Finger */ \
100 | AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_1, /* 4 */ \
101 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
102 | USAGE, 0x22, /* Usage: Finger */ \
103 | AAPL_WELLSPRING_8_PTP_FINGER_COLLECTION_2, /* 5 */ \
104 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
105 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
106 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
107 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
109 | USAGE, 0x56, /* Usage: Scan Time */ \
110 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
111 | USAGE, 0x54, /* Usage: Contact Count */ \
112 | LOGICAL_MAXIMUM, 0x7f, \
113 | REPORT_SIZE, 0x08, \
114 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
115 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
116 | USAGE, 0x01, /* Button 1 */ \
117 | LOGICAL_MAXIMUM, 0x01, \
118 | REPORT_SIZE, 0x01, \
119 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
120 | REPORT_COUNT, 0x07, \
121 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
122 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
123 | REPORT_ID, REPORTID_DEVICE_CAPS, \
124 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
125 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
126 | LOGICAL_MINIMUM, 0x00, \
127 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
128 | REPORT_SIZE, 0x08, \
129 | REPORT_COUNT, 0x02, \
130 | FEATURE, 0x02, \
131 | USAGE_PAGE_1, 0x00, 0xff, \
132 | REPORT_ID, REPORTID_PTPHQA, \
133 | USAGE, 0xc5, \
134 | LOGICAL_MINIMUM, 0x00, \
135 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
136 | REPORT_SIZE, 0x08, \
137 | REPORT_COUNT_2, 0x00, 0x01, \
138 | FEATURE, 0x02, \
139 | END_COLLECTION /* End Collection */
140 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/DeviceFamily/WellspringMt2.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1 \
6 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
7 | /* Begin a byte */ \
8 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
9 | USAGE, 0x47, /* Usage: Confidence */ \
10 | USAGE, 0x42, /* Usage: Tip switch */ \
11 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
12 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
13 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
14 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
15 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
16 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
17 | /* End of a byte */ \
18 | /* Begin of 4 bytes */ \
19 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
20 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
21 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
22 | USAGE, 0x51, /* Usage: Contract Identifier */ \
23 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
24 | /* End of 4 bytes */ \
25 | /* Begin of 4 bytes */ \
26 | /* Size is hard-coded at this moment */ \
27 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
28 | LOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \
29 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
30 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
31 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
32 | USAGE, 0x30, /* Usage: X */ \
33 | PHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \
34 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
35 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
36 | PHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \
37 | LOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \
38 | USAGE, 0x31, /* Usage: Y */ \
39 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
40 | PHYSICAL_MAXIMUM, 0x00, /* Physical Maximum: 0 */ \
41 | UNIT_EXPONENT, 0x00, /* Unit exponent: 0 */ \
42 | UNIT, 0x00, /* Unit: None */ \
43 | /* End of 4 bytes */ \
44 | END_COLLECTION /* End Collection */ \
45 |
46 | #define AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2 \
47 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
48 | /* Begin a byte */ \
49 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 1 */ \
50 | USAGE, 0x47, /* Usage: Confidence */ \
51 | USAGE, 0x42, /* Usage: Tip switch */ \
52 | REPORT_COUNT, 0x02, /* Report Count: 2 */ \
53 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
54 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
55 | REPORT_SIZE, 0x01, /* Report Size: 1 */ \
56 | REPORT_COUNT, 0x06, /* Report Count: 6 */ \
57 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
58 | /* End of a byte */ \
59 | /* Begin of 4 bytes */ \
60 | REPORT_COUNT, 0x01, /* Report Count: 1 */ \
61 | REPORT_SIZE, 0x20, /* Report Size: 0x20 (4 bytes) */ \
62 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0xff, 0xff, /* Logical Maximum: 0xffffffff */ \
63 | USAGE, 0x51, /* Usage: Contract Identifier */ \
64 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
65 | /* End of 4 bytes */ \
66 | /* Begin of 4 bytes */ \
67 | /* Size is hard-coded at this moment */ \
68 | USAGE_PAGE, 0x01, /* Usage Page: Generic Desktop */ \
69 | LOGICAL_MAXIMUM_2, 0xbc, 0x1d, /* Logical Maximum: 7612 (See defintion) */ \
70 | REPORT_SIZE, 0x10, /* Report Size: 0x10 (2 bytes) */ \
71 | UNIT_EXPONENT, 0x0e, /* Unit exponent: -2 */ \
72 | UNIT, 0x11, /* Unit: SI Length (cm) */ \
73 | USAGE, 0x30, /* Usage: X */ \
74 | PHYSICAL_MAXIMUM_2, 0x40, 0x06, /* Physical Maximum: 1600 (See Apple Spec) */ \
75 | REPORT_COUNT, 0x01, /* Report count: 1 */ \
76 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
77 | PHYSICAL_MAXIMUM_2, 0x7d, 0x04, /* Physical Maximum: 1149 (See Apple Spec) */ \
78 | LOGICAL_MAXIMUM_2, 0xc9, 0x13, /* Logical Maximum: 5065 (See definition) */ \
79 | USAGE, 0x31, /* Usage: Y */ \
80 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
81 | /* End of 4 bytes */ \
82 | END_COLLECTION /* End Collection */ \
83 |
84 | #define AAPL_MAGIC_TRACKPAD2_PTP_TLC \
85 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
86 | USAGE, 0x05, /* Usage: Touch Pad */ \
87 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
88 | REPORT_ID, REPORTID_MULTITOUCH, /* Report ID: Multi-touch */ \
89 | USAGE, 0x22, /* Usage: Finger */ \
90 | AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 1 */ \
91 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
92 | USAGE, 0x22, /* Usage: Finger */ \
93 | AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 2 */ \
94 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
95 | USAGE, 0x22, /* Usage: Finger */ \
96 | AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 3 */ \
97 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
98 | USAGE, 0x22, /* Usage: Finger */ \
99 | AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_1, /* 4 */ \
100 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
101 | USAGE, 0x22, /* Usage: Finger */ \
102 | AAPL_MAGIC_TRACKPAD2_PTP_FINGER_COLLECTION_2, /* 5 */ \
103 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
104 | UNIT_EXPONENT, 0x0c, /* Unit exponent: -4 */ \
105 | UNIT_2, 0x01, 0x10, /* Time: Second */ \
106 | PHYSICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
107 | LOGICAL_MAXIMUM_3, 0xff, 0xff, 0x00, 0x00, \
108 | USAGE, 0x56, /* Usage: Scan Time */ \
109 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
110 | USAGE, 0x54, /* Usage: Contact Count */ \
111 | LOGICAL_MAXIMUM, 0x7f, \
112 | REPORT_SIZE, 0x08, \
113 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
114 | USAGE_PAGE, 0x09, /* Usage Page: Button */ \
115 | USAGE, 0x01, /* Button 1 */ \
116 | LOGICAL_MAXIMUM, 0x01, \
117 | REPORT_SIZE, 0x01, \
118 | INPUT, 0x02, /* Input: (Data, Var, Abs) */ \
119 | REPORT_COUNT, 0x07, \
120 | INPUT, 0x03, /* Input: (Const, Var, Abs) */ \
121 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
122 | REPORT_ID, REPORTID_DEVICE_CAPS, \
123 | USAGE, 0x55, /* Usage: Maximum Contacts */ \
124 | USAGE, 0x59, /* Usage: Touchpad Button Type*/ \
125 | LOGICAL_MINIMUM, 0x00, \
126 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
127 | REPORT_SIZE, 0x08, \
128 | REPORT_COUNT, 0x02, \
129 | FEATURE, 0x02, \
130 | USAGE_PAGE_1, 0x00, 0xff, \
131 | REPORT_ID, REPORTID_PTPHQA, \
132 | USAGE, 0xc5, \
133 | LOGICAL_MINIMUM, 0x00, \
134 | LOGICAL_MAXIMUM_2, 0xff, 0x00, \
135 | REPORT_SIZE, 0x08, \
136 | REPORT_COUNT_2, 0x00, 0x01, \
137 | FEATURE, 0x02, \
138 | END_COLLECTION /* End Collection */
139 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/Driver.h:
--------------------------------------------------------------------------------
1 | // Driver.h: Driver definitions
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | // ModernTrace is for runtime debugging
11 | // Trace is WPP-based, development debugging
12 | #include
13 | #include
14 |
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | EXTERN_C_START
21 |
22 | //
23 | // WDFDRIVER Events
24 | //
25 |
26 | DRIVER_INITIALIZE DriverEntry;
27 | EVT_WDF_DRIVER_DEVICE_ADD AmtPtpDeviceEvtDeviceAdd;
28 | EVT_WDF_OBJECT_CONTEXT_CLEANUP AmtPtpDeviceEvtDriverContextCleanup;
29 |
30 |
31 | //
32 | // Driver initialization routines
33 | //
34 |
35 | VOID
36 | DriverTraceInit(
37 | _In_ PDRIVER_OBJECT DriverObject,
38 | _In_ PUNICODE_STRING RegistryPath
39 | );
40 |
41 | VOID
42 | DriverTraceCleanup(
43 | _In_ WDFOBJECT DriverObject
44 | );
45 |
46 | EXTERN_C_END
47 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/Hid.h:
--------------------------------------------------------------------------------
1 | // Hid.h: Device-related HID definitions
2 | #pragma once
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | // Device family metadata
10 | #include "DeviceFamily/Wellspring3.h"
11 | #include "DeviceFamily/Wellspring5.h"
12 | #include "DeviceFamily/Wellspring6.h"
13 | #include "DeviceFamily/Wellspring7A.h"
14 | #include "DeviceFamily/Wellspring8.h"
15 | #include "DeviceFamily/WellspringMt2.h"
16 |
17 | typedef UCHAR HID_REPORT_DESCRIPTOR, *PHID_REPORT_DESCRIPTOR;
18 |
19 | #define DEVICE_VERSION 0x01
20 | #define DEVICE_VID 0x8910
21 |
22 | #define AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC \
23 | USAGE_PAGE_1, 0x00, 0xff, /* Usage Page: Vendor defined */ \
24 | USAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \
25 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
26 | REPORT_ID, REPORTID_UMAPP_CONF, /* Report ID: User-mode Application configuration */ \
27 | USAGE, 0x01, /* Usage: Vendor Usage 0x01 */ \
28 | LOGICAL_MINIMUM, 0x00, /* Logical Minimum 0 */ \
29 | LOGICAL_MAXIMUM_2, 0xff, 0x00, /* Logical Maximum 255 */ \
30 | REPORT_SIZE, 0x08, /* Report Size: 8 */ \
31 | REPORT_COUNT, 0x03, /* Report Count: 3 */ \
32 | FEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \
33 | END_COLLECTION
34 |
35 | #define AAPL_PTP_WINDOWS_CONFIGURATION_TLC \
36 | USAGE_PAGE, 0x0d, /* Usage Page: Digitizer */ \
37 | USAGE, 0x0e, /* Usage: Configuration */ \
38 | BEGIN_COLLECTION, 0x01, /* Begin Collection: Application */ \
39 | REPORT_ID, REPORTID_REPORTMODE, /* Report ID: Mode Selection */ \
40 | USAGE, 0x22, /* Usage: Finger */ \
41 | BEGIN_COLLECTION, 0x02, /* Begin Collection: Logical */ \
42 | USAGE, 0x52, /* Usage: Input Mode */ \
43 | LOGICAL_MINIMUM, 0x00, /* Logical Minumum: 0 finger */ \
44 | LOGICAL_MAXIMUM, MAX_FINGERS, /* Logical Maximum: MAX_TOUCH_COUNT fingers */ \
45 | REPORT_SIZE, 0x08, /* Report Size: 0x08 */ \
46 | REPORT_COUNT, 0x01, /* Report Count: 0x01 */ \
47 | FEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \
48 | END_COLLECTION, /* End Collection */ \
49 | BEGIN_COLLECTION, 0x00, /* Begin Collection: Physical */ \
50 | REPORT_ID, REPORTID_FUNCSWITCH, /* Report ID: Function Switch */ \
51 | USAGE, BUTTON_SWITCH, /* Usage: Button Switch */ \
52 | USAGE, SURFACE_SWITCH, /* Usage: Surface Switch */ \
53 | REPORT_SIZE, 0x01, /* Report Size: 0x01 */ \
54 | REPORT_COUNT, 0x02, /* Report Count: 0x02 */ \
55 | LOGICAL_MAXIMUM, 0x01, /* Logical Maximum: 0x01 */ \
56 | FEATURE, 0x02, /* Feature: (Data, Var, Abs) */ \
57 | REPORT_COUNT, 0x06, /* Report Count: 0x06 */ \
58 | FEATURE, 0x03, /* Feature: (Const, Var, Abs) */ \
59 | END_COLLECTION, /* End Collection */ \
60 | END_COLLECTION /* End Collection */
61 |
62 | #define DEFAULT_PTP_HQA_BLOB \
63 | 0xfc, 0x28, 0xfe, 0x84, 0x40, 0xcb, 0x9a, 0x87, \
64 | 0x0d, 0xbe, 0x57, 0x3c, 0xb6, 0x70, 0x09, 0x88, \
65 | 0x07, 0x97, 0x2d, 0x2b, 0xe3, 0x38, 0x34, 0xb6, \
66 | 0x6c, 0xed, 0xb0, 0xf7, 0xe5, 0x9c, 0xf6, 0xc2, \
67 | 0x2e, 0x84, 0x1b, 0xe8, 0xb4, 0x51, 0x78, 0x43, \
68 | 0x1f, 0x28, 0x4b, 0x7c, 0x2d, 0x53, 0xaf, 0xfc, \
69 | 0x47, 0x70, 0x1b, 0x59, 0x6f, 0x74, 0x43, 0xc4, \
70 | 0xf3, 0x47, 0x18, 0x53, 0x1a, 0xa2, 0xa1, 0x71, \
71 | 0xc7, 0x95, 0x0e, 0x31, 0x55, 0x21, 0xd3, 0xb5, \
72 | 0x1e, 0xe9, 0x0c, 0xba, 0xec, 0xb8, 0x89, 0x19, \
73 | 0x3e, 0xb3, 0xaf, 0x75, 0x81, 0x9d, 0x53, 0xb9, \
74 | 0x41, 0x57, 0xf4, 0x6d, 0x39, 0x25, 0x29, 0x7c, \
75 | 0x87, 0xd9, 0xb4, 0x98, 0x45, 0x7d, 0xa7, 0x26, \
76 | 0x9c, 0x65, 0x3b, 0x85, 0x68, 0x89, 0xd7, 0x3b, \
77 | 0xbd, 0xff, 0x14, 0x67, 0xf2, 0x2b, 0xf0, 0x2a, \
78 | 0x41, 0x54, 0xf0, 0xfd, 0x2c, 0x66, 0x7c, 0xf8, \
79 | 0xc0, 0x8f, 0x33, 0x13, 0x03, 0xf1, 0xd3, 0xc1, \
80 | 0x0b, 0x89, 0xd9, 0x1b, 0x62, 0xcd, 0x51, 0xb7, \
81 | 0x80, 0xb8, 0xaf, 0x3a, 0x10, 0xc1, 0x8a, 0x5b, \
82 | 0xe8, 0x8a, 0x56, 0xf0, 0x8c, 0xaa, 0xfa, 0x35, \
83 | 0xe9, 0x42, 0xc4, 0xd8, 0x55, 0xc3, 0x38, 0xcc, \
84 | 0x2b, 0x53, 0x5c, 0x69, 0x52, 0xd5, 0xc8, 0x73, \
85 | 0x02, 0x38, 0x7c, 0x73, 0xb6, 0x41, 0xe7, 0xff, \
86 | 0x05, 0xd8, 0x2b, 0x79, 0x9a, 0xe2, 0x34, 0x60, \
87 | 0x8f, 0xa3, 0x32, 0x1f, 0x09, 0x78, 0x62, 0xbc, \
88 | 0x80, 0xe3, 0x0f, 0xbd, 0x65, 0x20, 0x08, 0x13, \
89 | 0xc1, 0xe2, 0xee, 0x53, 0x2d, 0x86, 0x7e, 0xa7, \
90 | 0x5a, 0xc5, 0xd3, 0x7d, 0x98, 0xbe, 0x31, 0x48, \
91 | 0x1f, 0xfb, 0xda, 0xaf, 0xa2, 0xa8, 0x6a, 0x89, \
92 | 0xd6, 0xbf, 0xf2, 0xd3, 0x32, 0x2a, 0x9a, 0xe4, \
93 | 0xcf, 0x17, 0xb7, 0xb8, 0xf4, 0xe1, 0x33, 0x08, \
94 | 0x24, 0x8b, 0xc4, 0x43, 0xa5, 0xe5, 0x24, 0xc2
95 |
96 | #define PTP_MAX_CONTACT_POINTS 5
97 | #define PTP_BUTTON_TYPE_CLICK_PAD 0
98 | #define PTP_BUTTON_TYPE_PRESSURE_PAD 1
99 |
100 | #define PTP_COLLECTION_MOUSE 0
101 | #define PTP_COLLECTION_WINDOWS 3
102 |
103 | #define PTP_CONTACT_CONFIDENCE_BIT 1
104 | #define PTP_CONTACT_TIPSWITCH_BIT 2
105 |
106 | typedef struct _HID_AAPL_MOUSE_REPORT {
107 | struct {
108 | UCHAR bButtons;
109 | UCHAR wXData;
110 | UCHAR wYData;
111 | UINT Padding;
112 | } InputReport;
113 | } HID_AAPL_MOUSE_REPORT, *PHID_AAPL_MOUSE_REPORT;
114 |
115 | typedef struct _HID_INPUT_REPORT {
116 | UCHAR ReportID;
117 | HID_AAPL_MOUSE_REPORT MouseReport;
118 | } HID_INPUT_REPORT, *PHID_INPUT_REPORT;
119 |
120 | typedef struct _PTP_DEVICE_CAPS_FEATURE_REPORT {
121 | UCHAR ReportID;
122 | UCHAR MaximumContactPoints;
123 | UCHAR ButtonType;
124 | } PTP_DEVICE_CAPS_FEATURE_REPORT, *PPTP_DEVICE_CAPS_FEATURE_REPORT;
125 |
126 | typedef struct _PTP_DEVICE_HQA_CERTIFICATION_REPORT {
127 | UCHAR ReportID;
128 | UCHAR CertificationBlob[256];
129 | } PTP_DEVICE_HQA_CERTIFICATION_REPORT, *PPTP_DEVICE_HQA_CERTIFICATION_REPORT;
130 |
131 | typedef struct _PTP_DEVICE_INPUT_MODE_REPORT {
132 | UCHAR ReportID;
133 | UCHAR Mode;
134 | } PTP_DEVICE_INPUT_MODE_REPORT, *PPTP_DEVICE_INPUT_MODE_REPORT;
135 |
136 | #pragma pack(1)
137 | typedef struct _PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT {
138 | UCHAR ReportID;
139 | UCHAR ButtonReport : 1;
140 | UCHAR SurfaceReport : 1;
141 | UCHAR Padding : 6;
142 | } PTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT, *PPTP_DEVICE_SELECTIVE_REPORT_MODE_REPORT;
143 | #pragma pack()
144 |
145 | #pragma pack(1)
146 | typedef struct _PTP_CONTACT {
147 | UCHAR Confidence : 1;
148 | UCHAR TipSwitch : 1;
149 | UCHAR Padding : 6;
150 | ULONG ContactID;
151 | USHORT X;
152 | USHORT Y;
153 | } PTP_CONTACT, *PPTP_CONTACT;
154 | #pragma pack()
155 |
156 | typedef struct _PTP_REPORT {
157 | UCHAR ReportID;
158 | PTP_CONTACT Contacts[5];
159 | USHORT ScanTime;
160 | UCHAR ContactCount;
161 | UCHAR IsButtonClicked;
162 | } PTP_REPORT, *PPTP_REPORT;
163 |
164 | typedef struct _PTP_USERMODEAPP_CONF_REPORT {
165 | UCHAR ReportID;
166 | UCHAR PressureQualificationLevel;
167 | UCHAR SingleContactSizeQualificationLevel;
168 | UCHAR MultipleContactSizeQualificationLevel;
169 | } PTP_USERMODEAPP_CONF_REPORT, *PPTP_USERMODEAPP_CONF_REPORT;
170 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/HidCommon.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #define REPORTID_STANDARDMOUSE 0x02
4 | #define REPORTID_MULTITOUCH 0x05
5 | #define REPORTID_REPORTMODE 0x04
6 | #define REPORTID_PTPHQA 0x08
7 | #define REPORTID_FUNCSWITCH 0x06
8 | #define REPORTID_DEVICE_CAPS 0x07
9 | #define REPORTID_UMAPP_CONF 0x09
10 |
11 | #define BUTTON_SWITCH 0x57
12 | #define SURFACE_SWITCH 0x58
13 |
14 | #define USAGE_PAGE 0x05
15 | #define USAGE_PAGE_1 0x06
16 | #define USAGE 0x09
17 | #define USAGE_MINIMUM 0x19
18 | #define USAGE_MAXIMUM 0x29
19 | #define LOGICAL_MINIMUM 0x15
20 | #define LOGICAL_MAXIMUM 0x25
21 | #define LOGICAL_MAXIMUM_2 0x26
22 | #define LOGICAL_MAXIMUM_3 0x27
23 | #define PHYSICAL_MINIMUM 0x35
24 | #define PHYSICAL_MAXIMUM 0x45
25 | #define PHYSICAL_MAXIMUM_2 0x46
26 | #define PHYSICAL_MAXIMUM_3 0x47
27 | #define UNIT_EXPONENT 0x55
28 | #define UNIT 0x65
29 | #define UNIT_2 0x66
30 |
31 | #define REPORT_ID 0x85
32 | #define REPORT_COUNT 0x95
33 | #define REPORT_COUNT_2 0x96
34 | #define REPORT_SIZE 0x75
35 | #define INPUT 0x81
36 | #define FEATURE 0xb1
37 |
38 | #define BEGIN_COLLECTION 0xa1
39 | #define END_COLLECTION 0xc0
40 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/ModernTrace.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | // This is the new Windows 10 trace logger provider
3 | #include
4 |
5 | EXTERN_C_START
6 |
7 | //
8 | // Declare TraceLogger Handler
9 | // TraceLogger GUID {871B1E2D-CC5A-4ADE-B74E-6CF1004EF149}
10 | // Do not confuse with WPP tracing
11 | //
12 | TRACELOGGING_DECLARE_PROVIDER(g_hAmtPtpDeviceTraceProvider);
13 |
14 | EXTERN_C_END
15 |
16 | //
17 | // Defines a set of events to use
18 | //
19 |
20 | #define EVENT_DRIVER_FUNCTIONAL "DriverFunctionalEvent"
21 | #define EVENT_DEVICE_IDENTIFICATION "DeviceIdentificationEvent"
22 | #define EVENT_DEVICE_USBOPERATION "DeviceUsbOperationEvent"
23 | #define EVENT_INPUT_DIAGNOSTICS "InputDiagnosticsEvent"
24 |
25 | #define EVENT_DRIVER_FUNC_SUBTYPE "Subtype"
26 | #define EVENT_DRIVER_FUNC_SUBTYPE_CRITFAIL "CriticalFailure"
27 | #define EVENT_DEVICE_ID_SUBTYPE_NOTFOUND "DeviceNotFoundInRegistry"
28 | #define EVENT_DEVICE_ID_SUBTYPE_HIDREG_NOTFOUND "DeviceDescriptorNotFoundInRegistry"
29 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/Queue.h:
--------------------------------------------------------------------------------
1 | // Queue.h: This file contains the queue definitions.
2 |
3 | EXTERN_C_START
4 |
5 | //
6 | // This is the context that can be placed per queue
7 | // and would contain per queue information.
8 | //
9 | typedef struct _QUEUE_CONTEXT {
10 |
11 | ULONG placeholder;
12 |
13 | } QUEUE_CONTEXT, *PQUEUE_CONTEXT;
14 |
15 | WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, QueueGetContext)
16 |
17 | _IRQL_requires_(PASSIVE_LEVEL)
18 | PCHAR
19 | DbgIoControlGetString(
20 | _In_ ULONG IoControlCode
21 | );
22 |
23 | NTSTATUS
24 | AmtPtpDeviceQueueInitialize(
25 | _In_ WDFDEVICE Device
26 | );
27 |
28 | NTSTATUS
29 | AmtPtpDispatchReadReportRequests(
30 | _In_ WDFDEVICE Device,
31 | _In_ WDFREQUEST Request,
32 | _Out_ BOOLEAN *Pending
33 | );
34 |
35 | //
36 | // Events from the IoQueue object
37 | //
38 | EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL AmtPtpDeviceEvtIoDeviceControl;
39 | EVT_WDF_IO_QUEUE_IO_STOP AmtPtpDeviceEvtIoStop;
40 |
41 | EXTERN_C_END
42 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/StaticHidRegistry.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef _AAPL_HID_DESCRIPTOR_H_
4 | #define _AAPL_HID_DESCRIPTOR_H_
5 |
6 | HID_REPORT_DESCRIPTOR AmtPtp3ReportDescriptor[] = {
7 | AAPL_WELLSPRING_3_PTP_TLC,
8 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
9 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
10 | };
11 |
12 | HID_REPORT_DESCRIPTOR AmtPtp5ReportDescriptor[] = {
13 | AAPL_WELLSPRING_5_PTP_TLC,
14 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
15 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
16 | };
17 |
18 | HID_REPORT_DESCRIPTOR AmtPtp6ReportDescriptor[] = {
19 | AAPL_WELLSPRING_6_PTP_TLC,
20 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
21 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
22 | };
23 |
24 | HID_REPORT_DESCRIPTOR AmtPtp7aReportDescriptor[] = {
25 | AAPL_WELLSPRING_7A_PTP_TLC,
26 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
27 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
28 | };
29 |
30 | HID_REPORT_DESCRIPTOR AmtPtp8ReportDescriptor[] = {
31 | AAPL_WELLSPRING_8_PTP_TLC,
32 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
33 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
34 | };
35 |
36 | HID_REPORT_DESCRIPTOR AmtPtpMt2ReportDescriptor[] = {
37 | AAPL_MAGIC_TRACKPAD2_PTP_TLC,
38 | AAPL_PTP_WINDOWS_CONFIGURATION_TLC,
39 | AAPL_PTP_USERMODE_CONFIGURATION_APP_TLC
40 | };
41 |
42 | HID_DESCRIPTOR AmtPtp3DefaultHidDescriptor = {
43 | 0x09, // bLength
44 | 0x21, // bDescriptorType
45 | 0x0100, // bcdHID
46 | 0x00, // bCountryCode
47 | 0x01, // bNumDescriptors
48 | {
49 | 0x22, // bDescriptorType
50 | sizeof(AmtPtp3ReportDescriptor) // bDescriptorLength
51 | },
52 | };
53 |
54 | HID_DESCRIPTOR AmtPtp5DefaultHidDescriptor = {
55 | 0x09, // bLength
56 | 0x21, // bDescriptorType
57 | 0x0100, // bcdHID
58 | 0x00, // bCountryCode
59 | 0x01, // bNumDescriptors
60 | {
61 | 0x22, // bDescriptorType
62 | sizeof(AmtPtp5ReportDescriptor) // bDescriptorLength
63 | },
64 | };
65 |
66 | HID_DESCRIPTOR AmtPtp6DefaultHidDescriptor = {
67 | 0x09, // bLength
68 | 0x21, // bDescriptorType
69 | 0x0100, // bcdHID
70 | 0x00, // bCountryCode
71 | 0x01, // bNumDescriptors
72 | {
73 | 0x22, // bDescriptorType
74 | sizeof(AmtPtp6ReportDescriptor) // bDescriptorLength
75 | },
76 | };
77 |
78 | HID_DESCRIPTOR AmtPtp7aDefaultHidDescriptor = {
79 | 0x09, // bLength
80 | 0x21, // bDescriptorType
81 | 0x0100, // bcdHID
82 | 0x00, // bCountryCode
83 | 0x01, // bNumDescriptors
84 | {
85 | 0x22, // bDescriptorType
86 | sizeof(AmtPtp7aReportDescriptor) // bDescriptorLength
87 | },
88 | };
89 |
90 | HID_DESCRIPTOR AmtPtp8DefaultHidDescriptor = {
91 | 0x09, // bLength
92 | 0x21, // bDescriptorType
93 | 0x0100, // bcdHID
94 | 0x00, // bCountryCode
95 | 0x01, // bNumDescriptors
96 | {
97 | 0x22, // bDescriptorType
98 | sizeof(AmtPtp8ReportDescriptor) // bDescriptorLength
99 | },
100 | };
101 |
102 | HID_DESCRIPTOR AmtPtpMt2DefaultHidDescriptor = {
103 | 0x09, // bLength
104 | 0x21, // bDescriptorType
105 | 0x0100, // bcdHID
106 | 0x00, // bCountryCode
107 | 0x01, // bNumDescriptors
108 | {
109 | 0x22, // bDescriptorType
110 | sizeof(AmtPtpMt2ReportDescriptor) // bDescriptorLength
111 | },
112 | };
113 |
114 | #endif
115 |
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/Trace.h:
--------------------------------------------------------------------------------
1 | // Trace.h: Local type definitions for tracing
2 |
3 | //
4 | // Device Interface GUID
5 | // 4a5064e5-7d39-41d1-a0e4-81097edce967
6 | //
7 | DEFINE_GUID(GUID_DEVINTERFACE_AmtPtpDevice,
8 | 0x4a5064e5, 0x7d39, 0x41d1, 0xa0, 0xe4, 0x81, 0x09, 0x7e, 0xdc, 0xe9, 0x67);
9 |
10 | //
11 | // Define the tracing flags.
12 | //
13 | // Tracing GUID - efc3ce99-43ff-4b59-afe4-c856e1afd8b0
14 | //
15 |
16 | #define WPP_CONTROL_GUIDS \
17 | WPP_DEFINE_CONTROL_GUID( \
18 | AmtPtpDriverTraceGuid, (efc3ce99,43ff,4b59,afe4,c856e1afd8b0), \
19 | \
20 | WPP_DEFINE_BIT(AMTPTPDRIVER_ALL_INFO) \
21 | WPP_DEFINE_BIT(TRACE_DRIVER) \
22 | WPP_DEFINE_BIT(TRACE_DEVICE) \
23 | WPP_DEFINE_BIT(TRACE_QUEUE) \
24 | WPP_DEFINE_BIT(TRACE_INPUT) \
25 | )
26 |
27 | #define WPP_FLAG_LEVEL_LOGGER(flag, level) \
28 | WPP_LEVEL_LOGGER(flag)
29 |
30 | #define WPP_FLAG_LEVEL_ENABLED(flag, level) \
31 | (WPP_LEVEL_ENABLED(flag) && \
32 | WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
33 |
34 | #define WPP_LEVEL_FLAGS_LOGGER(lvl,flags) \
35 | WPP_LEVEL_LOGGER(flags)
36 |
37 | #define WPP_LEVEL_FLAGS_ENABLED(lvl, flags) \
38 | (WPP_LEVEL_ENABLED(flags) && WPP_CONTROL(WPP_BIT_ ## flags).Level >= lvl)
39 |
40 | //
41 | // This comment block is scanned by the trace preprocessor to define our
42 | // Trace function.
43 | //
44 | // begin_wpp config
45 | // FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
46 | // FUNC TraceEvents(LEVEL, FLAGS, MSG, ...);
47 | // end_wpp
48 | //
--------------------------------------------------------------------------------
/AmtPtpDeviceUsbUm/include/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Resource.rc
4 |
5 | #define IDS_APP_TITLE 103
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 101
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is the Precision Touchpad driver for the Magic Trackpad 2 that I personally use on my PCs. It is based entirely on the excellent [imbushuo driver](https://github.com/imbushuo/mac-precision-touchpad) and solves a number of problems explained in the "Context" section below. This is an image of the Control Panel: (each option is an additional feature built on top of the "vanilla" imbushuo driver)
2 |
3 | 
4 |
5 | # Context
6 |
7 | In terms of hardware, the Magic Trackpad 2 is the best external touchpad you can buy (not just for macOS), by far. In terms of software, specifically for Windows, AFAIK there are 4 options to use it: Trackpad++, Magic Utilities, the excellent [open source driver by imbushuo](https://github.com/imbushuo/mac-precision-touchpad) and the [official 2021 Apple driver](https://github.com/lc700x/MagicTrackPad2_Windows_Precision_Drivers). In my opinion the two options that offer the best feeling, experience and stability (using the MT2 via USB at least) are the last two (imbushuo and Apple drivers) which coincidentally are extremely similar according to my tests (in terms of "feeling", and they are the only 2 that present the MT2 as a Precision Touchpad to Windows). Unfortunately these two solutions present different pointer precision problems. One problem is that of "near field fingers", i.e. the trackpad registers movements and clicks even without physically touching the trackpad surface, at a distance of even one millimeter from the surface. Another issue (determined by the first) is the accuracy of the pointer when you lift your finger from the trackpad. Furthermore, AFAIK, with both the imbushuo driver and the Apple one, it is not possible to adjust the behavior of the haptic feedback.
8 |
9 | A few months ago, I discovered [this excellent PR](https://github.com/imbushuo/mac-precision-touchpad/pull/533) of [1Revenger1](https://github.com/1Revenger1) to the imbushuo repo (which unfortunately hasn't been updated for 3 years). This PR solves the "near field fingers" problem. It also removes the QueryPerformanceCounter call in the interrupt function, instead setting the timestamp of the reports to the value returned by the Magic Trackpad itself (this may seem secondary but it is important, since using the MT2 in conditions of heavy PC load can determine returning inaccurate timestamps due to delayed thread scheduling). This PR convinced me that it might be worth investing some time in trying to solve all the other problems that made using MT2 more uncomfortable on PC than on macOS: I added the Control Panel, the ability to control the MT2's haptic feedback and other pointer precision options which I personally found useful.
10 |
11 | I'm really happy with the result: the feeling of the MT2 is identical to that of the touchpad of my laptop and very similar to that of the MT2 when used in macOS (pointer acceleration is different, but this is not determined by the driver).
12 |
13 | **Additional Credits**: The haptic feedback control messages sent by the driver to the MT2 in this project are based on the excellent reverse engineering work of [dos1](https://github.com/dos1) ([here](https://github.com/mwyborski/Linux-Magic-Trackpad-2-Driver/issues/28#issuecomment-451625504)).
14 |
15 | **License**: This project has the same license as the imbushuo project, on which it is entirely based.
16 |
17 | # Installation
18 |
19 | **NOTE**: Only for the MT2 when connected via USB, ie bluetooth not supported.
20 |
21 | 1) Connect the MT2 to the PC via USB and first install the imbushuo driver: download [this file (for x86)](https://github.com/imbushuo/mac-precision-touchpad/releases/download/2105-3979/Drivers-amd64-ReleaseMSSigned.zip) or [this file (for ARM)](https://github.com/imbushuo/mac-precision-touchpad/releases/download/2105-3979/Drivers-arm64-ReleaseMSSigned.zip), unzip it, right-click on the INF file and click "Install".
22 |
23 | 2) Download the zip file of this project from the [Releases](https://github.com/vitoplantamura/MagicTrackpad2ForWindows/releases) of this repo, unzip it, start the Control Panel and click on "Install Driver".
24 |
25 | # How the Installation Works
26 |
27 | The imbushuo MT2 USB driver is a UMDF driver. Windows Driver Signature Enforcement does not block the loading of self-signed UMDF drivers. This unfortunately does not apply to KMDF drivers such as the imbushuo bluetooth driver for the MT2 and this is the reason why this project only supports the USB version of the driver. On a personal note I prefer to use the MT2 via USB: the MT2 can be switched between different computers without problems, no worries about the battery, the driver cannot bluescreen the PC and the USB version of the imbushuo driver in particular has proven to be very stable over the years.
28 |
29 | When you click on "Install Driver" in the Control Panel, all MT2s connected to the system are disabled and then the AmtPtpDeviceUsbUm.dll file is updated directly in the Windows Driver Store. The owner and ACL of the file are modified to allow copying, and are restored to their original state at the end of the procedure. At the end of the copy, the MT2 is re-enabled. This procedure is not supported by Microsoft, but is commonly used during driver development and does not put system security at risk (as long as the file you are copying is trusted).
30 |
31 | **If your Magic Trackpad 2 is with Lightning Port (before Oct 2024), the installation is finished. If it is with USB-C (after Oct 2024) then this further step is necessary:**
32 |
33 | Manually choose the drivers in Device Manager for the Human Interface Devices with the Instance Path that matches this: ```USB\VID_05AC&PID_0324&MI_00\***``` & ```USB\VID_05AC&PID_0324&MI_01\***``` to be the Apple USB Precision Touchpad Device (User-mode) by Bingxing Wang (imbushuo). This can be done by double-clicking the device item in Device Manager -> (Details Tab) Update Driver -> Browse my computer for drivers -> Pick from list of drivers -> Uncheck Show compatible hardware.
34 |
--------------------------------------------------------------------------------
/assets/ControlPanel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maashrafh/MagicTrackpad2ForWindows/971609319bd85e80e667ae8445b9b1053fadef66/assets/ControlPanel.png
--------------------------------------------------------------------------------