1use std::{any::TypeId, collections::HashMap, sync::Arc};
5
6use lazy_static::lazy_static;
7
8use super::Feature;
9use crate::{
10 channel::HidppChannel,
11 feature::{
12 CreatableFeature, device_friendly_name::DeviceFriendlyNameFeature,
13 device_information::DeviceInformationFeature,
14 device_type_and_name::DeviceTypeAndNameFeature, feature_set::FeatureSetFeature,
15 hires_wheel::HiResWheelFeature, root::RootFeature, smartshift::SmartShiftFeature,
16 thumbwheel::ThumbwheelFeature, unified_battery::UnifiedBatteryFeature,
17 wireless_device_status::WirelessDeviceStatusFeature,
18 },
19};
20
21pub type FeatureImplProducer =
24 fn(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> (TypeId, Arc<dyn Feature>);
25
26#[derive(Clone, Copy, Debug, Hash)]
29pub struct FeatureVersion {
30 pub starting_version: u8,
32
33 pub producer: FeatureImplProducer,
35}
36
37#[derive(Clone, Copy, Debug, Hash)]
39pub struct KnownFeature {
40 pub name: &'static str,
44
45 pub versions: &'static [FeatureVersion],
48}
49
50pub fn lookup(feature_id: u16) -> Option<KnownFeature> {
52 KNOWN_FEATURES.get(&feature_id).copied()
53}
54
55pub fn lookup_version(feature_id: u16, feature_version: u8) -> Option<Vec<FeatureVersion>> {
58 lookup(feature_id).map(|feat| {
59 feat.versions
60 .iter()
61 .filter(|&ver| ver.starting_version <= feature_version)
62 .copied()
63 .collect::<Vec<FeatureVersion>>()
64 })
65}
66
67fn new_dyn<F: CreatableFeature>(
69 chan: Arc<HidppChannel>,
70 device_index: u8,
71 feature_index: u8,
72) -> (TypeId, Arc<dyn Feature>) {
73 (
74 TypeId::of::<F>(),
75 Arc::new(F::new(chan, device_index, feature_index)),
76 )
77}
78
79lazy_static! {
80 static ref KNOWN_FEATURES: HashMap<u16, KnownFeature> = HashMap::from([
81 (
82 0x0000,
83 KnownFeature {
84 name: "Root",
85 versions: &[FeatureVersion {
86 starting_version: RootFeature::STARTING_VERSION,
87 producer: new_dyn::<RootFeature>
88 }]
89 }
90 ),
91 (
92 0x0001,
93 KnownFeature {
94 name: "FeatureSet",
95 versions: &[FeatureVersion {
96 starting_version: FeatureSetFeature::STARTING_VERSION,
97 producer: new_dyn::<FeatureSetFeature>
98 }]
99 }
100 ),
101 (
102 0x0002,
103 KnownFeature {
104 name: "FeatureInfo",
105 versions: &[]
106 }
107 ),
108 (
109 0x0003,
110 KnownFeature {
111 name: "DeviceInformation",
112 versions: &[FeatureVersion {
113 starting_version: DeviceInformationFeature::STARTING_VERSION,
114 producer: new_dyn::<DeviceInformationFeature>
115 }]
116 }
117 ),
118 (
119 0x0004,
120 KnownFeature {
121 name: "UnitId",
122 versions: &[]
123 }
124 ),
125 (
126 0x0005,
127 KnownFeature {
128 name: "DeviceTypeAndName",
129 versions: &[FeatureVersion {
130 starting_version: DeviceTypeAndNameFeature::STARTING_VERSION,
131 producer: new_dyn::<DeviceTypeAndNameFeature>
132 }]
133 }
134 ),
135 (
136 0x0006,
137 KnownFeature {
138 name: "DeviceGroups",
139 versions: &[]
140 }
141 ),
142 (
143 0x0007,
144 KnownFeature {
145 name: "DeviceFriendlyName",
146 versions: &[FeatureVersion {
147 starting_version: DeviceFriendlyNameFeature::STARTING_VERSION,
148 producer: new_dyn::<DeviceFriendlyNameFeature>
149 }]
150 }
151 ),
152 (
153 0x0008,
154 KnownFeature {
155 name: "KeepAlive",
156 versions: &[]
157 }
158 ),
159 (
160 0x0020,
161 KnownFeature {
162 name: "ConfigChange",
163 versions: &[]
164 }
165 ),
166 (
167 0x0021,
168 KnownFeature {
169 name: "UniqueRandomId",
170 versions: &[]
171 }
172 ),
173 (
174 0x0030,
175 KnownFeature {
176 name: "TargetSoftware",
177 versions: &[]
178 }
179 ),
180 (
181 0x0080,
182 KnownFeature {
183 name: "WirelessSignalStrength",
184 versions: &[]
185 }
186 ),
187 (
188 0x00c0,
189 KnownFeature {
190 name: "DfuControlLegacy",
191 versions: &[]
192 }
193 ),
194 (
195 0x00c1,
196 KnownFeature {
197 name: "DfuControlUnsigned",
198 versions: &[]
199 }
200 ),
201 (
202 0x00c2,
203 KnownFeature {
204 name: "DfuControlSigned",
205 versions: &[]
206 }
207 ),
208 (
209 0x00c3,
210 KnownFeature {
211 name: "DfuControlBolt",
212 versions: &[]
213 }
214 ),
215 (
216 0x00d0,
217 KnownFeature {
218 name: "Dfu",
219 versions: &[]
220 }
221 ),
222 (
223 0x00d1,
224 KnownFeature {
225 name: "DfuResumable",
226 versions: &[]
227 }
228 ),
229 (
230 0x1000,
231 KnownFeature {
232 name: "BatteryStatus",
233 versions: &[]
234 }
235 ),
236 (
237 0x1001,
238 KnownFeature {
239 name: "BatteryVoltage",
240 versions: &[]
241 }
242 ),
243 (
244 0x1004,
245 KnownFeature {
246 name: "UnifiedBattery",
247 versions: &[FeatureVersion {
248 starting_version: UnifiedBatteryFeature::STARTING_VERSION,
249 producer: new_dyn::<UnifiedBatteryFeature>
250 }]
251 }
252 ),
253 (
254 0x1010,
255 KnownFeature {
256 name: "ChargingControl",
257 versions: &[]
258 }
259 ),
260 (
261 0x1300,
262 KnownFeature {
263 name: "LedControl",
264 versions: &[]
265 }
266 ),
267 (
268 0x1800,
269 KnownFeature {
270 name: "GenericTest",
271 versions: &[]
272 }
273 ),
274 (
275 0x1802,
276 KnownFeature {
277 name: "DeviceReset",
278 versions: &[]
279 }
280 ),
281 (
282 0x1805,
283 KnownFeature {
284 name: "OobState",
285 versions: &[]
286 }
287 ),
288 (
289 0x1806,
290 KnownFeature {
291 name: "ConfigDeviceProps",
292 versions: &[]
293 }
294 ),
295 (
296 0x1814,
297 KnownFeature {
298 name: "ChangeHost",
299 versions: &[]
300 }
301 ),
302 (
303 0x1815,
304 KnownFeature {
305 name: "HostsInfo",
306 versions: &[]
307 }
308 ),
309 (
310 0x1981,
311 KnownFeature {
312 name: "Backlight1",
313 versions: &[]
314 }
315 ),
316 (
317 0x1982,
318 KnownFeature {
319 name: "Backlight2",
320 versions: &[]
321 }
322 ),
323 (
324 0x1983,
325 KnownFeature {
326 name: "Backlight3",
327 versions: &[]
328 }
329 ),
330 (
331 0x1990,
332 KnownFeature {
333 name: "Illumination",
334 versions: &[]
335 }
336 ),
337 (
338 0x19b0,
339 KnownFeature {
340 name: "HapticFeedback",
341 versions: &[]
342 }
343 ),
344 (
345 0x19c0,
346 KnownFeature {
347 name: "ForceSensingButton",
348 versions: &[]
349 }
350 ),
351 (
352 0x1a00,
353 KnownFeature {
354 name: "PresenterControl",
355 versions: &[]
356 }
357 ),
358 (
359 0x1a01,
360 KnownFeature {
361 name: "Sensor3D",
362 versions: &[]
363 }
364 ),
365 (
366 0x1b00,
367 KnownFeature {
368 name: "ReprogControls",
369 versions: &[]
370 }
371 ),
372 (
373 0x1b01,
374 KnownFeature {
375 name: "ReprogControls2",
376 versions: &[]
377 }
378 ),
379 (
380 0x1b02,
381 KnownFeature {
382 name: "ReprogControls3",
383 versions: &[]
384 }
385 ),
386 (
387 0x1b03,
388 KnownFeature {
389 name: "ReprogControls4",
390 versions: &[]
391 }
392 ),
393 (
394 0x1b04,
395 KnownFeature {
396 name: "ReprogControls5",
397 versions: &[]
398 }
399 ),
400 (
401 0x1bc0,
402 KnownFeature {
403 name: "ReportHidUsages",
404 versions: &[]
405 }
406 ),
407 (
408 0x1c00,
409 KnownFeature {
410 name: "PersistentRemappableAction",
411 versions: &[]
412 }
413 ),
414 (
415 0x1d4b,
416 KnownFeature {
417 name: "WirelessDeviceStatus",
418 versions: &[FeatureVersion {
419 starting_version: WirelessDeviceStatusFeature::STARTING_VERSION,
420 producer: new_dyn::<WirelessDeviceStatusFeature>
421 }]
422 }
423 ),
424 (
425 0x1df0,
426 KnownFeature {
427 name: "RemainingPairings",
428 versions: &[]
429 }
430 ),
431 (
432 0x1f1f,
433 KnownFeature {
434 name: "FirmwareProperties",
435 versions: &[]
436 }
437 ),
438 (
439 0x1f20,
440 KnownFeature {
441 name: "AdcMeasurement",
442 versions: &[]
443 }
444 ),
445 (
446 0x2001,
447 KnownFeature {
448 name: "SwapLeftRightButton",
449 versions: &[]
450 }
451 ),
452 (
453 0x2005,
454 KnownFeature {
455 name: "ButtonSwapCancel",
456 versions: &[]
457 }
458 ),
459 (
460 0x2006,
461 KnownFeature {
462 name: "PointerAxesOrientation",
463 versions: &[]
464 }
465 ),
466 (
467 0x2100,
468 KnownFeature {
469 name: "VerticalScrolling",
470 versions: &[]
471 }
472 ),
473 (
474 0x2110,
475 KnownFeature {
476 name: "SmartShiftWheel",
477 versions: &[FeatureVersion {
478 starting_version: SmartShiftFeature::STARTING_VERSION,
479 producer: new_dyn::<SmartShiftFeature>
480 }]
481 }
482 ),
483 (
484 0x2111,
485 KnownFeature {
486 name: "SmartShiftWheelEnhanced",
487 versions: &[]
488 }
489 ),
490 (
491 0x2120,
492 KnownFeature {
493 name: "HighResolutionScrolling",
494 versions: &[]
495 }
496 ),
497 (
498 0x2121,
499 KnownFeature {
500 name: "HiResWheel",
501 versions: &[FeatureVersion {
502 starting_version: HiResWheelFeature::STARTING_VERSION,
503 producer: new_dyn::<HiResWheelFeature>
504 }]
505 }
506 ),
507 (
508 0x2130,
509 KnownFeature {
510 name: "RatchetWheel",
511 versions: &[]
512 }
513 ),
514 (
515 0x2150,
516 KnownFeature {
517 name: "Thumbwheel",
518 versions: &[FeatureVersion {
519 starting_version: ThumbwheelFeature::STARTING_VERSION,
520 producer: new_dyn::<ThumbwheelFeature>
521 }]
522 }
523 ),
524 (
525 0x2200,
526 KnownFeature {
527 name: "MousePointer",
528 versions: &[]
529 }
530 ),
531 (
532 0x2201,
533 KnownFeature {
534 name: "AdjustableDpi",
535 versions: &[]
536 }
537 ),
538 (
539 0x2202,
540 KnownFeature {
541 name: "ExtendedAdjustableDpi",
542 versions: &[]
543 }
544 ),
545 (
546 0x2205,
547 KnownFeature {
548 name: "PointerMotionScaling",
549 versions: &[]
550 }
551 ),
552 (
553 0x2230,
554 KnownFeature {
555 name: "SensorAngleSnapping",
556 versions: &[]
557 }
558 ),
559 (
560 0x2240,
561 KnownFeature {
562 name: "SurfaceTuning",
563 versions: &[]
564 }
565 ),
566 (
567 0x2250,
568 KnownFeature {
569 name: "XyStats",
570 versions: &[]
571 }
572 ),
573 (
574 0x2251,
575 KnownFeature {
576 name: "WheelStats",
577 versions: &[]
578 }
579 ),
580 (
581 0x2400,
582 KnownFeature {
583 name: "HybridTrackingEngine",
584 versions: &[]
585 }
586 ),
587 (
588 0x40a0,
589 KnownFeature {
590 name: "FnInversion",
591 versions: &[]
592 }
593 ),
594 (
595 0x40a2,
596 KnownFeature {
597 name: "FnInversionWithDefaultState",
598 versions: &[]
599 }
600 ),
601 (
602 0x40a3,
603 KnownFeature {
604 name: "FnInversionForMultiHostDevices",
605 versions: &[]
606 }
607 ),
608 (
609 0x4100,
610 KnownFeature {
611 name: "Encryption",
612 versions: &[]
613 }
614 ),
615 (
616 0x4220,
617 KnownFeature {
618 name: "LockKeyState",
619 versions: &[]
620 }
621 ),
622 (
623 0x4301,
624 KnownFeature {
625 name: "SolarKeyboardDashboard",
626 versions: &[]
627 }
628 ),
629 (
630 0x4520,
631 KnownFeature {
632 name: "KeyboardLayout",
633 versions: &[]
634 }
635 ),
636 (
637 0x4521,
638 KnownFeature {
639 name: "DisableKeys",
640 versions: &[]
641 }
642 ),
643 (
644 0x4522,
645 KnownFeature {
646 name: "DisableKeysByUsage",
647 versions: &[]
648 }
649 ),
650 (
651 0x4530,
652 KnownFeature {
653 name: "DualPlatform",
654 versions: &[]
655 }
656 ),
657 (
658 0x4531,
659 KnownFeature {
660 name: "MultiPlatform",
661 versions: &[]
662 }
663 ),
664 (
665 0x4540,
666 KnownFeature {
667 name: "KeyboardInternationalLayouts",
668 versions: &[]
669 }
670 ),
671 (
672 0x4600,
673 KnownFeature {
674 name: "Crown",
675 versions: &[]
676 }
677 ),
678 (
679 0x6010,
680 KnownFeature {
681 name: "TouchpadFwItems",
682 versions: &[]
683 }
684 ),
685 (
686 0x6011,
687 KnownFeature {
688 name: "TouchpadSwItems",
689 versions: &[]
690 }
691 ),
692 (
693 0x6012,
694 KnownFeature {
695 name: "TouchpadWin8FwItems",
696 versions: &[]
697 }
698 ),
699 (
700 0x6020,
701 KnownFeature {
702 name: "TapEnable",
703 versions: &[]
704 }
705 ),
706 (
707 0x6021,
708 KnownFeature {
709 name: "TapEnableExtended",
710 versions: &[]
711 }
712 ),
713 (
714 0x6030,
715 KnownFeature {
716 name: "CursorBallistic",
717 versions: &[]
718 }
719 ),
720 (
721 0x6040,
722 KnownFeature {
723 name: "TouchpadResolutionDivider",
724 versions: &[]
725 }
726 ),
727 (
728 0x6100,
729 KnownFeature {
730 name: "TouchpadRawXy",
731 versions: &[]
732 }
733 ),
734 (
735 0x6110,
736 KnownFeature {
737 name: "TouchMouseRawTouchPoints",
738 versions: &[]
739 }
740 ),
741 (
742 0x6120,
743 KnownFeature {
744 name: "BtTouchMouseSettings",
745 versions: &[]
746 }
747 ),
748 (
749 0x6500,
750 KnownFeature {
751 name: "Gestures1",
752 versions: &[]
753 }
754 ),
755 (
756 0x6501,
757 KnownFeature {
758 name: "Gestures2",
759 versions: &[]
760 }
761 ),
762 (
763 0x8010,
764 KnownFeature {
765 name: "GamingGKeys",
766 versions: &[]
767 }
768 ),
769 (
770 0x8020,
771 KnownFeature {
772 name: "GamingMKeys",
773 versions: &[]
774 }
775 ),
776 (
777 0x8030,
778 KnownFeature {
779 name: "MacroRecord",
780 versions: &[]
781 }
782 ),
783 (
784 0x8040,
785 KnownFeature {
786 name: "BrightnessControl",
787 versions: &[]
788 }
789 ),
790 (
791 0x8060,
792 KnownFeature {
793 name: "AdjustableReportRate",
794 versions: &[]
795 }
796 ),
797 (
798 0x8061,
799 KnownFeature {
800 name: "ExtendedAdjustableReportRate",
801 versions: &[]
802 }
803 ),
804 (
805 0x8070,
806 KnownFeature {
807 name: "ColorLedEffects",
808 versions: &[]
809 }
810 ),
811 (
812 0x8071,
813 KnownFeature {
814 name: "RgbEffects",
815 versions: &[]
816 }
817 ),
818 (
819 0x8080,
820 KnownFeature {
821 name: "PerKeyLighting",
822 versions: &[]
823 }
824 ),
825 (
826 0x8081,
827 KnownFeature {
828 name: "PerKeyLighting2",
829 versions: &[]
830 }
831 ),
832 (
833 0x8090,
834 KnownFeature {
835 name: "ModeStatus",
836 versions: &[]
837 }
838 ),
839 (
840 0x8100,
841 KnownFeature {
842 name: "OnboardProfiles",
843 versions: &[]
844 }
845 ),
846 (
847 0x8110,
848 KnownFeature {
849 name: "MouseButtonFilter",
850 versions: &[]
851 }
852 ),
853 (
854 0x8111,
855 KnownFeature {
856 name: "LatencyMonitoring",
857 versions: &[]
858 }
859 ),
860 (
861 0x8120,
862 KnownFeature {
863 name: "GamingAttachments",
864 versions: &[]
865 }
866 ),
867 (
868 0x8123,
869 KnownFeature {
870 name: "ForceFeedback",
871 versions: &[]
872 }
873 ),
874 (
875 0x8300,
876 KnownFeature {
877 name: "Sidetone",
878 versions: &[]
879 }
880 ),
881 (
882 0x8310,
883 KnownFeature {
884 name: "Equalizer",
885 versions: &[]
886 }
887 ),
888 (
889 0x8320,
890 KnownFeature {
891 name: "HeadsetOut",
892 versions: &[]
893 }
894 ),
895 ]);
896}