ohmu
·
2026-10-15
1#include "host.h"
2#include "common/strutil.h"
3
4const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel) {
5 // Macbook Pro: https://support.apple.com/en-us/HT201300
6 // Macbook Air: https://support.apple.com/en-us/HT201862
7 // Mac mini: https://support.apple.com/en-us/HT201894
8 // iMac: https://support.apple.com/en-us/HT201634
9 // Mac Pro: https://support.apple.com/en-us/HT202888
10 // Mac Studio: https://support.apple.com/en-us/HT213073
11
12 if (ffStrbufStartsWithS(hwModel, "MacBookPro")) {
13 const char* version = hwModel->chars + strlen("MacBookPro");
14 if (ffStrEquals(version, "18,3") ||
15 ffStrEquals(version, "18,4")) {
16 return "MacBook Pro (14-inch, 2021)";
17 }
18 if (ffStrEquals(version, "18,1") ||
19 ffStrEquals(version, "18,2")) {
20 return "MacBook Pro (16-inch, 2021)";
21 }
22 if (ffStrEquals(version, "17,1")) {
23 return "MacBook Pro (13-inch, M1, 2020)";
24 }
25 if (ffStrEquals(version, "16,3")) {
26 return "MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)";
27 }
28 if (ffStrEquals(version, "16,2")) {
29 return "MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)";
30 }
31 if (ffStrEquals(version, "16,4") ||
32 ffStrEquals(version, "16,1")) {
33 return "MacBook Pro (16-inch, 2019)";
34 }
35 if (ffStrEquals(version, "15,4")) {
36 return "MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)";
37 }
38 if (ffStrEquals(version, "15,3")) {
39 return "MacBook Pro (15-inch, 2019)";
40 }
41 if (ffStrEquals(version, "15,2")) {
42 return "MacBook Pro (13-inch, 2018/2019, Four Thunderbolt 3 ports)";
43 }
44 if (ffStrEquals(version, "15,1")) {
45 return "MacBook Pro (15-inch, 2018/2019)";
46 }
47 if (ffStrEquals(version, "14,3")) {
48 return "MacBook Pro (15-inch, 2017)";
49 }
50 if (ffStrEquals(version, "14,2")) {
51 return "MacBook Pro (13-inch, 2017, Four Thunderbolt 3 ports)";
52 }
53 if (ffStrEquals(version, "14,1")) {
54 return "MacBook Pro (13-inch, 2017, Two Thunderbolt 3 ports)";
55 }
56 if (ffStrEquals(version, "13,3")) {
57 return "MacBook Pro (15-inch, 2016)";
58 }
59 if (ffStrEquals(version, "13,2")) {
60 return "MacBook Pro (13-inch, 2016, Four Thunderbolt 3 ports)";
61 }
62 if (ffStrEquals(version, "13,1")) {
63 return "MacBook Pro (13-inch, 2016, Two Thunderbolt 3 ports)";
64 }
65 if (ffStrEquals(version, "12,1")) {
66 return "MacBook Pro (Retina, 13-inch, Early 2015)";
67 }
68 if (ffStrEquals(version, "11,4") ||
69 ffStrEquals(version, "11,5")) {
70 return "MacBook Pro (Retina, 15-inch, Mid 2015)";
71 }
72 if (ffStrEquals(version, "11,2") ||
73 ffStrEquals(version, "11,3")) {
74 return "MacBook Pro (Retina, 15-inch, Late 2013/Mid 2014)";
75 }
76 if (ffStrEquals(version, "11,1")) {
77 return "MacBook Pro (Retina, 13-inch, Late 2013/Mid 2014)";
78 }
79 if (ffStrEquals(version, "10,2")) {
80 return "MacBook Pro (Retina, 13-inch, Late 2012/Early 2013)";
81 }
82 if (ffStrEquals(version, "10,1")) {
83 return "MacBook Pro (Retina, 15-inch, Mid 2012/Early 2013)";
84 }
85 if (ffStrEquals(version, "9,2")) {
86 return "MacBook Pro (13-inch, Mid 2012)";
87 }
88 if (ffStrEquals(version, "9,1")) {
89 return "MacBook Pro (15-inch, Mid 2012)";
90 }
91 if (ffStrEquals(version, "8,3")) {
92 return "MacBook Pro (17-inch, 2011)";
93 }
94 if (ffStrEquals(version, "8,2")) {
95 return "MacBook Pro (15-inch, 2011)";
96 }
97 if (ffStrEquals(version, "8,1")) {
98 return "MacBook Pro (13-inch, 2011)";
99 }
100 if (ffStrEquals(version, "7,1")) {
101 return "MacBook Pro (13-inch, Mid 2010)";
102 }
103 if (ffStrEquals(version, "6,2")) {
104 return "MacBook Pro (15-inch, Mid 2010)";
105 }
106 if (ffStrEquals(version, "6,1")) {
107 return "MacBook Pro (17-inch, Mid 2010)";
108 }
109 if (ffStrEquals(version, "5,5")) {
110 return "MacBook Pro (13-inch, Mid 2009)";
111 }
112 if (ffStrEquals(version, "5,3")) {
113 return "MacBook Pro (15-inch, Mid 2009)";
114 }
115 if (ffStrEquals(version, "5,2")) {
116 return "MacBook Pro (17-inch, Mid/Early 2009)";
117 }
118 if (ffStrEquals(version, "5,1")) {
119 return "MacBook Pro (15-inch, Late 2008)";
120 }
121 if (ffStrEquals(version, "4,1")) {
122 return "MacBook Pro (17/15-inch, Early 2008)";
123 }
124 } else if (ffStrbufStartsWithS(hwModel, "MacBookAir")) {
125 const char* version = hwModel->chars + strlen("MacBookAir");
126 if (ffStrEquals(version, "10,1")) {
127 return "MacBook Air (M1, 2020)";
128 }
129 if (ffStrEquals(version, "9,1")) {
130 return "MacBook Air (Retina, 13-inch, 2020)";
131 }
132 if (ffStrEquals(version, "8,2")) {
133 return "MacBook Air (Retina, 13-inch, 2019)";
134 }
135 if (ffStrEquals(version, "8,1")) {
136 return "MacBook Air (Retina, 13-inch, 2018)";
137 }
138 if (ffStrEquals(version, "7,2")) {
139 return "MacBook Air (13-inch, Early 2015/2017)";
140 }
141 if (ffStrEquals(version, "7,1")) {
142 return "MacBook Air (11-inch, Early 2015)";
143 }
144 if (ffStrEquals(version, "6,2")) {
145 return "MacBook Air (13-inch, Mid 2013/Early 2014)";
146 }
147 if (ffStrEquals(version, "6,1")) {
148 return "MacBook Air (11-inch, Mid 2013/Early 2014)";
149 }
150 if (ffStrEquals(version, "5,2")) {
151 return "MacBook Air (13-inch, Mid 2012)";
152 }
153 if (ffStrEquals(version, "5,1")) {
154 return "MacBook Air (11-inch, Mid 2012)";
155 }
156 if (ffStrEquals(version, "4,2")) {
157 return "MacBook Air (13-inch, Mid 2011)";
158 }
159 if (ffStrEquals(version, "4,1")) {
160 return "MacBook Air (11-inch, Mid 2011)";
161 }
162 if (ffStrEquals(version, "3,2")) {
163 return "MacBook Air (13-inch, Late 2010)";
164 }
165 if (ffStrEquals(version, "3,1")) {
166 return "MacBook Air (11-inch, Late 2010)";
167 }
168 if (ffStrEquals(version, "2,1")) {
169 return "MacBook Air (Mid 2009)";
170 }
171 } else if (ffStrbufStartsWithS(hwModel, "Macmini")) {
172 const char* version = hwModel->chars + strlen("Macmini");
173 if (ffStrEquals(version, "9,1")) {
174 return "Mac mini (M1, 2020)";
175 }
176 if (ffStrEquals(version, "8,1")) {
177 return "Mac mini (2018)";
178 }
179 if (ffStrEquals(version, "7,1")) {
180 return "Mac mini (Mid 2014)";
181 }
182 if (ffStrEquals(version, "6,1") ||
183 ffStrEquals(version, "6,2")) {
184 return "Mac mini (Late 2012)";
185 }
186 if (ffStrEquals(version, "5,1") ||
187 ffStrEquals(version, "5,2")) {
188 return "Mac mini (Mid 2011)";
189 }
190 if (ffStrEquals(version, "4,1")) {
191 return "Mac mini (Mid 2010)";
192 }
193 if (ffStrEquals(version, "3,1")) {
194 return "Mac mini (Early/Late 2009)";
195 }
196 } else if (ffStrbufStartsWithS(hwModel, "MacBook")) {
197 const char* version = hwModel->chars + strlen("MacBook");
198 if (ffStrEquals(version, "10,1")) {
199 return "MacBook (Retina, 12-inch, 2017)";
200 }
201 if (ffStrEquals(version, "9,1")) {
202 return "MacBook (Retina, 12-inch, Early 2016)";
203 }
204 if (ffStrEquals(version, "8,1")) {
205 return "MacBook (Retina, 12-inch, Early 2015)";
206 }
207 if (ffStrEquals(version, "7,1")) {
208 return "MacBook (13-inch, Mid 2010)";
209 }
210 if (ffStrEquals(version, "6,1")) {
211 return "MacBook (13-inch, Late 2009)";
212 }
213 if (ffStrEquals(version, "5,2")) {
214 return "MacBook (13-inch, Early/Mid 2009)";
215 }
216 } else if (ffStrbufStartsWithS(hwModel, "MacPro")) {
217 const char* version = hwModel->chars + strlen("MacPro");
218 if (ffStrEquals(version, "7,1")) {
219 return "Mac Pro (2019)";
220 }
221 if (ffStrEquals(version, "6,1")) {
222 return "Mac Pro (Late 2013)";
223 }
224 if (ffStrEquals(version, "5,1")) {
225 return "Mac Pro (Mid 2010 - Mid 2012)";
226 }
227 if (ffStrEquals(version, "4,1")) {
228 return "Mac Pro (Early 2009)";
229 }
230 } else if (ffStrbufStartsWithS(hwModel, "Mac")) {
231 const char* version = hwModel->chars + strlen("Mac");
232 if (ffStrEquals(version, "18,5")) {
233 return "Mac Mini (M6, 2026)";
234 }
235 if (ffStrEquals(version, "17,16")) {
236 return "Mac Mini (M5 Pro, 2026)";
237 }
238 if (ffStrEquals(version, "17,15")) {
239 return "Mac Studio (M5 Ultra, 2026)";
240 }
241 if (ffStrEquals(version, "17,14")) {
242 return "Mac Studio (M5 Max, 2026)";
243 }
244 if (ffStrEquals(version, "17,9")) {
245 return "MacBook Pro (14-inch, M5 Pro, 2026)";
246 }
247 if (ffStrEquals(version, "17,8")) {
248 return "MacBook Pro (16-inch, M5 Pro, 2026)";
249 }
250 if (ffStrEquals(version, "17,7")) {
251 return "MacBook Pro (14-inch, M5 Max, 2026)";
252 }
253 if (ffStrEquals(version, "17,6")) {
254 return "MacBook Pro (16-inch, M5 Max, 2026)";
255 }
256 if (ffStrEquals(version, "17,5")) {
257 return "MacBook Neo (13-inch, A18 Pro, 2026)";
258 }
259 if (ffStrEquals(version, "17,4")) {
260 return "MacBook Air (15-inch, M5, 2026)";
261 }
262 if (ffStrEquals(version, "17,3")) {
263 return "MacBook Air (13-inch, M5, 2026)";
264 }
265 if (ffStrEquals(version, "17,2")) {
266 return "MacBook Pro (14-inch, M5, 2025)";
267 }
268 if (ffStrEquals(version, "16,13")) {
269 return "MacBook Air (15-inch, M4, 2025)";
270 }
271 if (ffStrEquals(version, "16,12")) {
272 return "MacBook Air (13-inch, M4, 2025)";
273 }
274 if (ffStrEquals(version, "16,11") ||
275 ffStrEquals(version, "16,10")) {
276 return "Mac Mini (2024)";
277 }
278 if (ffStrEquals(version, "16,9")) {
279 return "Mac Studio (M4 Max, 2025)";
280 }
281 if (ffStrEquals(version, "16,3")) {
282 return "iMac (24-inch, 2024, Four Thunderbolt / USB 4 ports)";
283 }
284 if (ffStrEquals(version, "16,2")) {
285 return "iMac (24-inch, 2024, Two Thunderbolt / USB 4 ports)";
286 }
287 if (ffStrEquals(version, "16,1")) {
288 return "MacBook Pro (14-inch, 2024, Three Thunderbolt 4 ports)";
289 }
290 if (ffStrEquals(version, "16,6") ||
291 ffStrEquals(version, "16,8")) {
292 return "MacBook Pro (14-inch, 2024, Three Thunderbolt 5 ports)";
293 }
294 if (ffStrEquals(version, "16,7") ||
295 ffStrEquals(version, "16,5")) {
296 return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)";
297 }
298 if (ffStrEquals(version, "15,14")) {
299 return "Mac Studio (M3 Ultra, 2025)";
300 }
301 if (ffStrEquals(version, "15,13")) {
302 return "MacBook Air (15-inch, M3, 2024)";
303 }
304 if (ffStrEquals(version, "15,12")) {
305 return "MacBook Air (13-inch, M3, 2024)";
306 }
307 if (ffStrEquals(version, "15,3")) {
308 return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)";
309 }
310 if (ffStrEquals(version, "15,4")) {
311 return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)";
312 }
313 if (ffStrEquals(version, "15,5")) {
314 return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
315 }
316 if (ffStrEquals(version, "15,6") ||
317 ffStrEquals(version, "15,8") ||
318 ffStrEquals(version, "15,10")) {
319 return "MacBook Pro (14-inch, Nov 2023, Three Thunderbolt 4 ports)";
320 }
321 if (ffStrEquals(version, "15,7") ||
322 ffStrEquals(version, "15,9") ||
323 ffStrEquals(version, "15,11")) {
324 return "MacBook Pro (16-inch, Nov 2023, Three Thunderbolt 4 ports)";
325 }
326 if (ffStrEquals(version, "14,15")) {
327 return "MacBook Air (15-inch, M2, 2023)";
328 }
329 if (ffStrEquals(version, "14,14")) {
330 return "Mac Studio (M2 Ultra, 2023, Two Thunderbolt 4 front ports)";
331 }
332 if (ffStrEquals(version, "14,13")) {
333 return "Mac Studio (M2 Max, 2023, Two USB-C front ports)";
334 }
335 if (ffStrEquals(version, "14,8")) {
336 return "Mac Pro (2023)";
337 }
338 if (ffStrEquals(version, "14,6") ||
339 ffStrEquals(version, "14,10")) {
340 return "MacBook Pro (16-inch, 2023)";
341 }
342 if (ffStrEquals(version, "14,5") ||
343 ffStrEquals(version, "14,9")) {
344 return "MacBook Pro (14-inch, 2023)";
345 }
346 if (ffStrEquals(version, "14,3")) {
347 return "Mac mini (M2, 2023, Two Thunderbolt 4 ports)";
348 }
349 if (ffStrEquals(version, "14,12")) {
350 return "Mac mini (M2 Pro, 2023, Four Thunderbolt 4 ports)";
351 }
352 if (ffStrEquals(version, "14,7")) {
353 return "MacBook Pro (13-inch, M2, 2022)";
354 }
355 if (ffStrEquals(version, "14,2")) {
356 return "MacBook Air (M2, 2022)";
357 }
358 if (ffStrEquals(version, "13,1")) {
359 return "Mac Studio (M1 Max, 2022, Two USB-C front ports)";
360 }
361 if (ffStrEquals(version, "13,2")) {
362 return "Mac Studio (M1 Ultra, 2022, Two Thunderbolt 4 front ports)";
363 }
364 } else if (ffStrbufStartsWithS(hwModel, "iMac")) {
365 const char* version = hwModel->chars + strlen("iMac");
366 if (ffStrEquals(version, "21,1")) {
367 return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports, Two USB 3 ports)";
368 }
369 if (ffStrEquals(version, "21,2")) {
370 return "iMac (24-inch, M1, 2021, Two Thunderbolt / USB 4 ports)";
371 }
372 if (ffStrEquals(version, "20,1") ||
373 ffStrEquals(version, "20,2")) {
374 return "iMac (Retina 5K, 27-inch, 2020)";
375 }
376 if (ffStrEquals(version, "19,1")) {
377 return "iMac (Retina 5K, 27-inch, 2019)";
378 }
379 if (ffStrEquals(version, "19,2")) {
380 return "iMac (Retina 4K, 21.5-inch, 2019)";
381 }
382 if (ffStrEquals(version, "Pro1,1")) {
383 return "iMac Pro (2017)";
384 }
385 if (ffStrEquals(version, "18,3")) {
386 return "iMac (Retina 5K, 27-inch, 2017)";
387 }
388 if (ffStrEquals(version, "18,2")) {
389 return "iMac (Retina 4K, 21.5-inch, 2017)";
390 }
391 if (ffStrEquals(version, "18,1")) {
392 return "iMac (21.5-inch, 2017)";
393 }
394 if (ffStrEquals(version, "17,1")) {
395 return "iMac (Retina 5K, 27-inch, Late 2015)";
396 }
397 if (ffStrEquals(version, "16,2")) {
398 return "iMac (Retina 4K, 21.5-inch, Late 2015)";
399 }
400 if (ffStrEquals(version, "16,1")) {
401 return "iMac (21.5-inch, Late 2015)";
402 }
403 if (ffStrEquals(version, "15,1")) {
404 return "iMac (Retina 5K, 27-inch, Late 2014 - Mid 2015)";
405 }
406 if (ffStrEquals(version, "14,4")) {
407 return "iMac (21.5-inch, Mid 2014)";
408 }
409 if (ffStrEquals(version, "14,2")) {
410 return "iMac (27-inch, Late 2013)";
411 }
412 if (ffStrEquals(version, "14,1")) {
413 return "iMac (21.5-inch, Late 2013)";
414 }
415 if (ffStrEquals(version, "13,2")) {
416 return "iMac (27-inch, Late 2012)";
417 }
418 if (ffStrEquals(version, "13,1")) {
419 return "iMac (21.5-inch, Late 2012)";
420 }
421 if (ffStrEquals(version, "12,2")) {
422 return "iMac (27-inch, Mid 2011)";
423 }
424 if (ffStrEquals(version, "12,1")) {
425 return "iMac (21.5-inch, Mid 2011)";
426 }
427 if (ffStrEquals(version, "11,3")) {
428 return "iMac (27-inch, Mid 2010)";
429 }
430 if (ffStrEquals(version, "11,2")) {
431 return "iMac (21.5-inch, Mid 2010)";
432 }
433 if (ffStrEquals(version, "10,1")) {
434 return "iMac (27/21.5-inch, Late 2009)";
435 }
436 if (ffStrEquals(version, "9,1")) {
437 return "iMac (24/20-inch, Early 2009)";
438 }
439 }
440 return nullptr;
441}
442
443#ifdef __x86_64__
444bool ffHostDetectMac(FFHostResult* host) {
445 if (ffStrbufStartsWithS(&host->family, "Mac") && ffStrbufEqualS(&host->vendor, "Apple Inc.")) {
446 const char* productName = ffHostGetMacProductNameWithHwModel(&host->name);
447 if (productName) {
448 ffStrbufDestroy(&host->family);
449 ffStrbufInitMove(&host->family, &host->name);
450 ffStrbufSetStatic(&host->name, productName);
451 return true;
452 }
453 }
454 return false;
455}
456#endif