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