diff --git a/app/include/zmk/behavior.h b/app/include/zmk/behavior.h index ad16af21..15045d9c 100644 --- a/app/include/zmk/behavior.h +++ b/app/include/zmk/behavior.h @@ -43,6 +43,19 @@ struct zmk_behavior_binding_event { */ const struct device *zmk_behavior_get_binding(const char *name); +/** + * @brief Invoke a behavior given its binding and invoking event details. + * + * @param src_binding Behavior binding to invoke. + * @param event The binding event struct containing details of the event that invoked it. + * @param pressed Whether the binding is pressed or released. + * + * @retval 0 If successful. + * @retval Negative errno code if failure. + */ +int zmk_invoke_behavior_binding(const struct zmk_behavior_binding *src_binding, + struct zmk_behavior_binding_event event, bool pressed); + /** * @brief Get a local ID for a behavior from its @p name field. * diff --git a/app/include/zmk/keymap.h b/app/include/zmk/keymap.h index ad2ac7e4..0d7dbaf3 100644 --- a/app/include/zmk/keymap.h +++ b/app/include/zmk/keymap.h @@ -7,7 +7,6 @@ #pragma once #include -#include #define ZMK_LAYER_CHILD_LEN_PLUS_ONE(node) 1 + #define ZMK_KEYMAP_LAYERS_LEN \ @@ -28,9 +27,6 @@ const char *zmk_keymap_layer_name(uint8_t layer); int zmk_keymap_position_state_changed(uint8_t source, uint32_t position, bool pressed, int64_t timestamp); -int zmk_invoke_behavior_binding(const struct zmk_behavior_binding *src_binding, - struct zmk_behavior_binding_event event, bool pressed); - #define ZMK_KEYMAP_EXTRACT_BINDING(idx, drv_inst) \ { \ .behavior_dev = DEVICE_DT_NAME(DT_PHANDLE_BY_IDX(drv_inst, bindings, idx)), \ diff --git a/app/src/behavior.c b/app/src/behavior.c index e69cdf88..78546754 100644 --- a/app/src/behavior.c +++ b/app/src/behavior.c @@ -17,11 +17,18 @@ #endif +#include +#if ZMK_BLE_IS_CENTRAL +#include +#endif + #include #include #include #include +#include + #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -49,6 +56,66 @@ const struct device *z_impl_behavior_get_binding(const char *name) { return NULL; } +static int invoke_locally(struct zmk_behavior_binding *binding, + struct zmk_behavior_binding_event event, bool pressed) { + if (pressed) { + return behavior_keymap_binding_pressed(binding, event); + } else { + return behavior_keymap_binding_released(binding, event); + } +} + +int zmk_invoke_behavior_binding(const struct zmk_behavior_binding *src_binding, + struct zmk_behavior_binding_event event, bool pressed) { + // We want to make a copy of this, since it may be converted from + // relative to absolute before being invoked + struct zmk_behavior_binding binding = *src_binding; + + const struct device *behavior = zmk_behavior_get_binding(binding.behavior_dev); + + if (!behavior) { + LOG_WRN("No behavior assigned to %d on layer %d", event.position, event.layer); + return 1; + } + + int err = behavior_keymap_binding_convert_central_state_dependent_params(&binding, event); + if (err) { + LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err); + return err; + } + + enum behavior_locality locality = BEHAVIOR_LOCALITY_CENTRAL; + err = behavior_get_locality(behavior, &locality); + if (err) { + LOG_ERR("Failed to get behavior locality %d", err); + return err; + } + + switch (locality) { + case BEHAVIOR_LOCALITY_CENTRAL: + return invoke_locally(&binding, event, pressed); + case BEHAVIOR_LOCALITY_EVENT_SOURCE: +#if ZMK_BLE_IS_CENTRAL + if (event.source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) { + return invoke_locally(&binding, event, pressed); + } else { + return zmk_split_bt_invoke_behavior(event.source, &binding, event, pressed); + } +#else + return invoke_locally(&binding, event, pressed); +#endif + case BEHAVIOR_LOCALITY_GLOBAL: +#if ZMK_BLE_IS_CENTRAL + for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) { + zmk_split_bt_invoke_behavior(i, &binding, event, pressed); + } +#endif + return invoke_locally(&binding, event, pressed); + } + + return -ENOTSUP; +} + #if IS_ENABLED(CONFIG_ZMK_BEHAVIOR_METADATA) int zmk_behavior_get_empty_param_metadata(const struct device *dev, diff --git a/app/src/behavior_queue.c b/app/src/behavior_queue.c index f0498201..081dfc28 100644 --- a/app/src/behavior_queue.c +++ b/app/src/behavior_queue.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include diff --git a/app/src/behaviors/behavior_hold_tap.c b/app/src/behaviors/behavior_hold_tap.c index 1e4f3fcf..71e15e53 100644 --- a/app/src/behaviors/behavior_hold_tap.c +++ b/app/src/behaviors/behavior_hold_tap.c @@ -18,7 +18,6 @@ #include #include #include -#include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); diff --git a/app/src/behaviors/behavior_mod_morph.c b/app/src/behaviors/behavior_mod_morph.c index 37ff67fe..b17822de 100644 --- a/app/src/behaviors/behavior_mod_morph.c +++ b/app/src/behaviors/behavior_mod_morph.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/app/src/keymap.c b/app/src/keymap.c index 486d133b..ea33725b 100644 --- a/app/src/keymap.c +++ b/app/src/keymap.c @@ -6,7 +6,6 @@ #include #include -#include #include LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); @@ -16,11 +15,6 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL); #include #include -#include -#if ZMK_BLE_IS_CENTRAL -#include -#endif - #include #include #include @@ -163,15 +157,6 @@ const char *zmk_keymap_layer_name(uint8_t layer) { return zmk_keymap_layer_names[layer]; } -int invoke_locally(struct zmk_behavior_binding *binding, struct zmk_behavior_binding_event event, - bool pressed) { - if (pressed) { - return behavior_keymap_binding_pressed(binding, event); - } else { - return behavior_keymap_binding_released(binding, event); - } -} - int zmk_keymap_apply_position_state(uint8_t source, int layer, uint32_t position, bool pressed, int64_t timestamp) { struct zmk_behavior_binding *binding = &zmk_keymap[layer][position]; @@ -187,57 +172,6 @@ int zmk_keymap_apply_position_state(uint8_t source, int layer, uint32_t position return zmk_invoke_behavior_binding(binding, event, pressed); } -int zmk_invoke_behavior_binding(const struct zmk_behavior_binding *src_binding, - struct zmk_behavior_binding_event event, bool pressed) { - // We want to make a copy of this, since it may be converted from - // relative to absolute before being invoked - struct zmk_behavior_binding binding = *src_binding; - - const struct device *behavior = zmk_behavior_get_binding(binding.behavior_dev); - - if (!behavior) { - LOG_WRN("No behavior assigned to %d on layer %d", event.position, event.layer); - return 1; - } - - int err = behavior_keymap_binding_convert_central_state_dependent_params(&binding, event); - if (err) { - LOG_ERR("Failed to convert relative to absolute behavior binding (err %d)", err); - return err; - } - - enum behavior_locality locality = BEHAVIOR_LOCALITY_CENTRAL; - err = behavior_get_locality(behavior, &locality); - if (err) { - LOG_ERR("Failed to get behavior locality %d", err); - return err; - } - - switch (locality) { - case BEHAVIOR_LOCALITY_CENTRAL: - return invoke_locally(&binding, event, pressed); - case BEHAVIOR_LOCALITY_EVENT_SOURCE: -#if ZMK_BLE_IS_CENTRAL - if (event.source == ZMK_POSITION_STATE_CHANGE_SOURCE_LOCAL) { - return invoke_locally(&binding, event, pressed); - } else { - return zmk_split_bt_invoke_behavior(event.source, &binding, event, pressed); - } -#else - return invoke_locally(&binding, event, pressed); -#endif - case BEHAVIOR_LOCALITY_GLOBAL: -#if ZMK_BLE_IS_CENTRAL - for (int i = 0; i < ZMK_SPLIT_BLE_PERIPHERAL_COUNT; i++) { - zmk_split_bt_invoke_behavior(i, &binding, event, pressed); - } -#endif - return invoke_locally(&binding, event, pressed); - } - - return -ENOTSUP; -} - int zmk_keymap_position_state_changed(uint8_t source, uint32_t position, bool pressed, int64_t timestamp) { if (pressed) {