/* * Copyright (c) 2022 The ZMK Contributors * * SPDX-License-Identifier: MIT */ #include #include #include #include #include #include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #define NUM_USB_PROFILES (COND_CODE_1(IS_ENABLED(CONFIG_ZMK_USB), (1), (0))) #define NUM_BLE_PROFILES (COND_CODE_1(IS_ENABLED(CONFIG_ZMK_BLE), (CONFIG_BT_MAX_CONN), (0))) #define NUM_PROFILES (NUM_USB_PROFILES + NUM_BLE_PROFILES) static zmk_led_indicators_flags_t led_flags[NUM_PROFILES]; static size_t profile_index(enum zmk_endpoint endpoint, uint8_t profile) { switch (endpoint) { case ZMK_ENDPOINT_USB: return 0; case ZMK_ENDPOINT_BLE: return NUM_USB_PROFILES + profile; } CODE_UNREACHABLE; } zmk_led_indicators_flags_t zmk_led_indicators_get_current_flags() { enum zmk_endpoint endpoint = zmk_endpoints_selected(); uint8_t profile = 0; #if IS_ENABLED(CONFIG_ZMK_BLE) if (endpoint == ZMK_ENDPOINT_USB) { profile = zmk_ble_active_profile_index(); } #endif return zmk_led_indicators_get_flags(endpoint, profile); } zmk_led_indicators_flags_t zmk_led_indicators_get_flags(enum zmk_endpoint endpoint, uint8_t profile) { size_t index = profile_index(endpoint, profile); return led_flags[index]; } static void raise_led_indicators_changed_event(struct k_work *_work) { ZMK_EVENT_RAISE(new_zmk_led_indicators_changed( (struct zmk_led_indicators_changed){.leds = zmk_led_indicators_get_current_flags()})); } static K_WORK_DEFINE(led_changed_work, raise_led_indicators_changed_event); void zmk_led_indicators_update_flags(zmk_led_indicators_flags_t leds, enum zmk_endpoint endpoint, uint8_t profile) { size_t index = profile_index(endpoint, profile); led_flags[index] = leds; k_work_submit(&led_changed_work); } void zmk_led_indicators_process_report(struct zmk_hid_led_report_body *report, enum zmk_endpoint endpoint, uint8_t profile) { zmk_led_indicators_flags_t leds = report->leds; zmk_led_indicators_update_flags(leds, endpoint, profile); LOG_DBG("Update LED indicators: endpoint=%d, profile=%d, flags=%x", endpoint, profile, leds); } static int endpoint_listener(const zmk_event_t *eh) { raise_led_indicators_changed_event(NULL); return 0; } static ZMK_LISTENER(endpoint_listener, endpoint_listener); static ZMK_SUBSCRIPTION(endpoint_listener, zmk_endpoint_selection_changed);