1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
56
57
58
59
60
61
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
mod color_percent;
mod sdk;
mod target_device;

pub use self::color_percent::ColorPercent;
pub use self::sdk::Sdk;
pub use self::target_device::TargetDevice;
pub use logitech_led_sdk_sys as sys;
use std::sync::Mutex;
pub use sys::LogiLed_DeviceType as DeviceType;
pub use sys::LogiLed_KeyName as KeyName;

/// The lock that syncs accesses to the SDK.
///
/// If you use raw sdk api functions anywhere, you MUST use this lock to wrap accesses to the sdk in order to prevent data races.
/// This library does all this for you, this is exposed only for users who want to use raw sdk functions safely.
pub static SDK_LOCK: Mutex<()> = Mutex::new(());

#[cfg(test)]
mod test {
    use super::*;
    use std::time::Duration;

    // A simple lock to ensure that only one test runs as a time.
    static TEST_LOCK: Mutex<()> = Mutex::new(());

    #[test]
    fn sanity_check() {
        let _test_lock = TEST_LOCK.lock().expect("test lock poisoned");

        // 1st init
        let sdk = Sdk::new().expect("failed to init LG SDK");
        std::thread::sleep(Duration::from_secs(5));
        drop(sdk);
        std::thread::sleep(Duration::from_secs(5));

        // 2nd init
        let sdk = Sdk::new_with_name("Test").expect("failed to init LG SDK");

        // 3rd init fails, we already opened the 2nd.
        assert!(Sdk::new().is_none());

        std::thread::sleep(Duration::from_secs(5));
        let _version = sdk.get_version().expect("failed to get LG SDK version");
        assert!(sdk.set_target(TargetDevice::All));
        assert!(sdk.set_lighting(ColorPercent::new_rgb(255, 255, 255)));
        assert!(sdk.set_lighting_for_key_with_name(KeyName::L, ColorPercent::new_rgb(0, 255, 255)));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Mouse,
            1,
            ColorPercent::new_rgb(255, 0, 0)
        ));
        assert!(sdk.flash_lighting(
            ColorPercent::new_rgb(255, 0, 0),
            Some(Duration::from_millis(10_000)),
            Duration::from_millis(100)
        ));
        assert!(sdk.stop_effects());
        assert!(sdk.pulse_lighting(
            ColorPercent::new_rgb(255, 0, 0),
            Some(Duration::from_millis(10_000)),
            Duration::from_millis(100)
        ));
        assert!(sdk.stop_effects());
        assert!(sdk.set_lighting_for_key_with_scan_code(16, ColorPercent::new_rgb(255, 255, 255)));
        assert!(sdk.set_lighting_for_key_with_hid_code(26, ColorPercent::new_rgb(255, 255, 255)));
        assert!(sdk.save_lighting_for_key(KeyName::L));
        assert!(sdk.restore_lighting_for_key(KeyName::L));
        assert!(sdk.flash_single_key(
            KeyName::L,
            ColorPercent::new_rgb(255, 0, 0),
            Some(Duration::from_millis(10_000)),
            Duration::from_millis(100)
        ));
        assert!(sdk.pulse_single_key(
            KeyName::L,
            ColorPercent::new_rgb(255, 0, 0),
            ColorPercent::new_rgb(255, 255, 0),
            Duration::from_millis(10_000),
            true
        ));
        assert!(sdk.stop_effects_on_key(KeyName::L));
        drop(sdk);
        std::thread::sleep(Duration::from_secs(5));
    }

    #[test]
    fn logi_set_target_zone_sample() {
        let _test_lock = TEST_LOCK.lock().expect("test lock poisoned");

        let sdk = Sdk::new_with_name("Test").expect("failed to init LG SDK");
        std::thread::sleep(Duration::from_secs(5));
        assert!(sdk.set_target(TargetDevice::All));
        assert!(sdk.set_lighting_for_key_with_name(KeyName::L, ColorPercent::new_rgb(0, 255, 255)));
        assert!(sdk.set_lighting_for_key_with_name(KeyName::O, ColorPercent::new_rgb(0, 255, 255)));
        assert!(sdk.set_lighting_for_key_with_name(KeyName::G, ColorPercent::new_rgb(0, 255, 255)));
        assert!(sdk.set_lighting_for_key_with_name(KeyName::I, ColorPercent::new_rgb(0, 255, 255)));

        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Mouse,
            1,
            ColorPercent::new_rgb(255, 0, 0)
        ));

        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Keyboard,
            1,
            ColorPercent::new_rgb(255, 0, 0)
        ));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Keyboard,
            2,
            ColorPercent::new_rgb(255, 255, 0)
        ));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Keyboard,
            3,
            ColorPercent::new_rgb(0, 255, 0)
        ));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Keyboard,
            4,
            ColorPercent::new_rgb(0, 255, 255)
        ));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Keyboard,
            5,
            ColorPercent::new_rgb(0, 0, 255)
        ));

        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Headset,
            0,
            ColorPercent::new_rgb(255, 255, 255)
        ));
        assert!(sdk.set_lighting_for_target_zone(
            DeviceType::Headset,
            1,
            ColorPercent::new_rgb(255, 0, 255)
        ));
        drop(sdk);
        std::thread::sleep(Duration::from_secs(5));
    }
}